package com.zmn.oms.business.impl.work.masterwork;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.zmn.base.channel.common.dro.ChannelDRO;
import com.zmn.base.channel.common.enums.ChannelLevelEnum;
import com.zmn.base.channel.dubbo.interfaces.channel.ChannelListRemoteService;
import com.zmn.base.common.data.common.dro.company.CompanyContactDRO;
import com.zmn.base.common.data.dubbo.interfaces.company.CompanyListRemoteService;
import com.zmn.base.engineer.common.constants.DubboConsts;
import com.zmn.base.engineer.common.dro.foreign.engineer.ForeignEngineerBasicInfoDRO;
import com.zmn.base.engineer.common.dro.supervisor.SupervisorBasicDRO;
import com.zmn.base.engineer.dubbo.interfaces.foreign.EngineerListRemoteService;
import com.zmn.base.engineer.dubbo.interfaces.supervisor.EngineerSupervisorListRemoteService;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderVisit;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWork;
import com.zmn.base.oms.common.model.es.orderwork.EsOrderWorkProduct;
import com.zmn.base.pilot.common.dto.pilot.PilotCheckQuery;
import com.zmn.base.pilot.common.enums.PilotTypeEnum;
import com.zmn.base.pilot.dubbo.interfaces.pilot.PilotRemoteService;
import com.zmn.base.price.common.dro.item.ItemPartsDRO;
import com.zmn.base.price.dubbo.interfaces.item.ItemPartsRemoteService;
import com.zmn.base.price.dubbo.interfaces.item.ItemTimeRemoteService;
import com.zmn.base.product.common.consts.BaseProductConsts;
import com.zmn.base.product.common.dto.categ.CategProductDRO;
import com.zmn.base.product.common.dto.categ.CategProductGroupDRO;
import com.zmn.base.product.common.query.categ.CategProductGroupQuery;
import com.zmn.base.product.common.query.categ.CategProductQuery;
import com.zmn.base.product.dubbo.interfaces.categ.CategProductListRemoteService;
import com.zmn.base.product.dubbo.interfaces.categ.serv.CategServProductListRemoteService;
import com.zmn.base.sdss.common.model.dio.oms.EngineerProductGroupCompositeScoreForDispatchOrderDIO;
import com.zmn.base.sdss.common.model.dro.oms.EngineerProductGroupCompositeScoreForDispatchOrderDRO;
import com.zmn.base.sdss.dubbo.interfaces.oms.CompositeServeScoreForOmsListRemoteService;
import com.zmn.biz.engineer.common.dro.distribute.EngineerTakeConfigDRO;
import com.zmn.biz.engineer.dubbo.interfaces.distribute.EngineerTakeConfigListRemoteService;
import com.zmn.comment.dubbo.interfaces.cmt.CmtCommentApiListRemoteService;
import com.zmn.comment.dubbo.interfaces.cmt.CmtCommentListRemoteService;
import com.zmn.common.constant.FicoConsts;
import com.zmn.common.constant.MasterConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.amount.AmountUtil;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.encode.EncodeUtil;
import com.zmn.common.utils.math.MoneyUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.dms.common.enums.DiscountTypeEnums;
import com.zmn.dms.common.enums.coup.ThirdPlatEnum;
import com.zmn.engstock.dubbo.interfaces.stock.StockListRemoteService;
import com.zmn.erp.common.newbiz.dio.ClearingOrderAccountDIO;
import com.zmn.erp.common.newbiz.dro.ClearingOrderAccountDRO;
import com.zmn.erp.dubbo.interfaces.newbiz.account.EngineerAccountRemoteService;
import com.zmn.manager.redis.RedisManager;
import com.zmn.oms.business.interfaces.apply.CancelApplyBService;
import com.zmn.oms.business.interfaces.attachment.AttachmentBService;
import com.zmn.oms.business.interfaces.base.BaseCodeService;
import com.zmn.oms.business.interfaces.conf.channel.ConfOrderChannelBService;
import com.zmn.oms.business.interfaces.es.OrderWorkEsBService;
import com.zmn.oms.business.interfaces.log.OrderLogBService;
import com.zmn.oms.business.interfaces.messageV1.common.MessageGetSendInfoService;
import com.zmn.oms.business.interfaces.messageV1.wechat.MessageWeChatTemplateService;
import com.zmn.oms.business.interfaces.mq.MqProviderService;
import com.zmn.oms.business.interfaces.orderamount.OrderDiscountCalcBService;
import com.zmn.oms.business.interfaces.orderattachment.OrderAttachmentBService;
import com.zmn.oms.business.interfaces.orderfinalpricequotation.OrderFinalPriceQuotationBService;
import com.zmn.oms.business.interfaces.orderstock.OrderStockBService;
import com.zmn.oms.business.interfaces.product.OrderProductExtendBService;
import com.zmn.oms.business.interfaces.remark.OrderRemarkBService;
import com.zmn.oms.business.interfaces.serviceitem.OrderServiceItemBService;
import com.zmn.oms.business.interfaces.servtype.ServItemBService;
import com.zmn.oms.business.interfaces.warranty.OrderWarrantyBService;
import com.zmn.oms.business.interfaces.work.OrderWorkAmountBService;
import com.zmn.oms.business.interfaces.work.OrderWorkERPQueryBService;
import com.zmn.oms.business.interfaces.work.OrderWorkListBService;
import com.zmn.oms.business.interfaces.work.OrderWorkProgrammeBService;
import com.zmn.oms.business.interfaces.work.masterwork.MasterWorkBService;
import com.zmn.oms.business.interfaces.worktrack.WorkTrackBService;
import com.zmn.oms.business.interfaces.xno.OrderXnoBindService;
import com.zmn.oms.common.annotation.ZsNormalOrderWorkLog;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.common.dio.attachment.ModifyOrderWorkAttachmentDIO;
import com.zmn.oms.common.dio.finalpricequotation.OrderFinalPriceQuotationDataDIO;
import com.zmn.oms.common.dro.attachment.WorkAttachmentDRO;
import com.zmn.oms.common.dro.conf.channel.ConfOrderChannelDRO;
import com.zmn.oms.common.enums.ConfChannelWorkOrderTypeEnum;
import com.zmn.oms.common.enums.RedistributeStatusEnum;
import com.zmn.oms.common.enums.WarrantyRuleEnum;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.utils.PremissUtil;
import com.zmn.oms.common.utils.ProductInfoUtil;
import com.zmn.oms.model.dro.master.MasterDoingOrderWorkDRO;
import com.zmn.oms.model.dto.fcorderpart.FcOrderPartCheckDTO;
import com.zmn.oms.model.dto.log.CallRecordLogDTO;
import com.zmn.oms.model.dto.orderattachment.ModifyOrderAttachmentDTO;
import com.zmn.oms.model.dto.orderattachment.OrderAttachmentAuditDTO;
import com.zmn.oms.model.dto.orderstock.LockStockDTO;
import com.zmn.oms.model.dto.orderstock.StockWhiteDTO;
import com.zmn.oms.model.dto.pay.AmountDTO;
import com.zmn.oms.model.dto.visit.OrderVisitDTO;
import com.zmn.oms.model.dto.work.masterwork.*;
import com.zmn.oms.model.dto.work.workamount.WorkUpdateAmountDTO;
import com.zmn.oms.model.entity.acceptance.OrderWorkAcceptance;
import com.zmn.oms.model.entity.acceptance.OrderWorkAcceptanceDbQuery;
import com.zmn.oms.model.entity.changerecord.OrderChangeRecord;
import com.zmn.oms.model.entity.detail.OrderDetail;
import com.zmn.oms.model.entity.discount.OrderDiscount;
import com.zmn.oms.model.entity.log.OrderLog;
import com.zmn.oms.model.entity.masterworking.MasterWorking;
import com.zmn.oms.model.entity.masterworking.MasterWorkingQuery;
import com.zmn.oms.model.entity.member.OrderMember;
import com.zmn.oms.model.entity.omstrack.OrderWorkTrack;
import com.zmn.oms.model.entity.operation.OrderOperation;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.orderappbind.OrderThirdAppBind;
import com.zmn.oms.model.entity.orderattachment.OrderAttachment;
import com.zmn.oms.model.entity.orderattachment.OrderAttachmentQuery;
import com.zmn.oms.model.entity.part.OrderPart;
import com.zmn.oms.model.entity.product.OrderProduct;
import com.zmn.oms.model.entity.product.OrderProductExtend;
import com.zmn.oms.model.entity.quotation3.OrderAcceptMaintainItem;
import com.zmn.oms.model.entity.quotation3.OrderQuotationProcess;
import com.zmn.oms.model.entity.redistribute.OrderWorkRedistributeApply;
import com.zmn.oms.model.entity.remark.OrderRemark;
import com.zmn.oms.model.entity.remark.OrderRemarkDetail;
import com.zmn.oms.model.entity.serviceitem.OrderServiceItem;
import com.zmn.oms.model.entity.tag.OrderTag;
import com.zmn.oms.model.entity.tamllextend.OrderTmallExtend;
import com.zmn.oms.model.entity.tamllextend.OrderTmallExtendQuery;
import com.zmn.oms.model.entity.track.OrderTrack;
import com.zmn.oms.model.entity.visit.OrderVisit;
import com.zmn.oms.model.entity.warranty.OrderWarranty;
import com.zmn.oms.model.entity.warranty.OrderWarrantyProduct;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.entity.work.OrderWorkQuery;
import com.zmn.oms.model.vo.remark.OrderRemarkDetailVO;
import com.zmn.oms.model.vo.remark.OrderRemarkVO;
import com.zmn.oms.model.vo.work.OrderVisitQrCodeVO;
import com.zmn.oms.model.vo.work.detail.ZsXnoBindVO;
import com.zmn.oms.model.vo.work.erp.SharingEstimateVO;
import com.zmn.oms.services.interfaces.acceptance.OrderWorkAcceptanceService;
import com.zmn.oms.services.interfaces.callrecord.OrderCallRecordService;
import com.zmn.oms.services.interfaces.changerecord.OrderChangeRecordService;
import com.zmn.oms.services.interfaces.detail.OrderDetailService;
import com.zmn.oms.services.interfaces.discount.OrderDiscountService;
import com.zmn.oms.services.interfaces.factory.OrderFactoryService;
import com.zmn.oms.services.interfaces.fcorderpart.OrderFactoryPartService;
import com.zmn.oms.services.interfaces.masterworking.MasterWorkingService;
import com.zmn.oms.services.interfaces.member.OrderMemberService;
import com.zmn.oms.services.interfaces.operation.OrderOperationService;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.orderattachment.OrderAttachmentService;
import com.zmn.oms.services.interfaces.orderencrypt.OrderEncryptService;
import com.zmn.oms.services.interfaces.orderpaydiscount.OrderPayDiscountService;
import com.zmn.oms.services.interfaces.part.OrderPartService;
import com.zmn.oms.services.interfaces.pay.OrderPayService;
import com.zmn.oms.services.interfaces.product.OrderProductService;
import com.zmn.oms.services.interfaces.quotation3.OrderAcceptMaintainItemService;
import com.zmn.oms.services.interfaces.quotation3.OrderQuotationProcessService;
import com.zmn.oms.services.interfaces.redistribute.OrderWorkRedistributeApplyService;
import com.zmn.oms.services.interfaces.remark.OrderRemarkDetailService;
import com.zmn.oms.services.interfaces.remark.OrderRemarkService;
import com.zmn.oms.services.interfaces.serviceitem.OrderServiceItemService;
import com.zmn.oms.services.interfaces.tag.OrderTagService;
import com.zmn.oms.services.interfaces.tmallextend.OrderTmallExtendService;
import com.zmn.oms.services.interfaces.track.OrderTrackService;
import com.zmn.oms.services.interfaces.visit.OrderVisitService;
import com.zmn.oms.services.interfaces.wallquotation.WallQuotationService;
import com.zmn.oms.services.interfaces.warranty.OrderWarrantyProductService;
import com.zmn.oms.services.interfaces.warranty.OrderWarrantyService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.services.interfaces.work.masterwork.MasterWorkService;
import com.zmn.pay.common.constant.PayConsts;
import com.zmn.performance.dubbo.interfaces.conf.five.ConfEngineerFiveListRemoteService;
import com.zmn.track.common.constant.TrackConfigConsts;
import com.zmn.track.common.constant.apply.cancel.CancelApplyConsts;
import com.zmn.track.dubbo.dio.apply.cancel.OrderCancelApplyQuery;
import com.zmn.track.dubbo.dro.apply.cancel.OrderCancelApplyDRO;
import com.zmn.track.dubbo.dro.apply.cancel.OrderCancelReasonDRO;
import com.zmn.track.dubbo.dto.TrackWorkDRO;
import com.zmn.track.dubbo.dto.TrackWorkQuery;
import com.zmn.track.dubbo.interfaces.apply.cancel.OrderCancelApplyListRemoteService;
import com.zmn.track.dubbo.interfaces.trackwork.TrackWorkListRemoteService;
import com.zmn.uuc.dubbo.interfaces.user.UserThirdListRemoteService;
import com.zmn.vas.dubbo.consts.VasDubboConsts;
import com.zmn.vas.dubbo.interfaces.order.VasOrderListRemoteService;
import com.zmn.xno.dubbo.interfaces.XnoRemoteService;
import io.shardingsphere.api.HintManager;
import javafx.util.Pair;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.hbase.thirdparty.com.google.common.collect.Streams;
import org.apache.lucene.search.join.ScoreMode;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;

/**
 * 类描述：工程师工单业务实现
 *
 * @author heciqi
 * @date 2018/11/02 21:02
 */
@Slf4j
@Primary
@Service
public class MasterWorkBServiceImpl implements MasterWorkBService {
    /**
     * 到家58显示提示消息的前台二级产品分类
     */
    public static final List<Integer> DAOJIA58_SHOWCATEGID_LIST = Lists
            .newArrayList(2697, 2698, 2699, 2696, 2702, 2701, 2700);

    public static final List<Integer> DAOJIA58_SHOWTPIS_CITY_LIST = Lists
            .newArrayList(210200, 440600, 440100, 520100, 330100, 320100, 370200, 350200, 440300, 130100, 420100,
                    430100, 330200, 440900, 320300, 120100);

    /**
     * 工程师修改预约时间次数保存时间，单位秒
     */
    public final static int MASTER_MODIFY_DUTY_TIME_COUNT_SECOND = 86400;

    public static final int SERV_CATEGE_APPLIANCE_REPAIR = 1002;

    /**
     * 用户报价URL-二维码
     */
    @Value("${weixin.quotation.qrcodeurl:'https://h5.xiujiadian.com/taximeter/?id=%s'}")
    private String quotationQrcodeUrl;

    @Autowired
    protected OrderWorkAmountBService orderWorkAmountBService;

    @Autowired
    OrderWorkService orderWorkService;

    @Autowired
    OrderPayService orderPayService;

    @Autowired
    OrderRemarkDetailService orderRemarkDetailService;

    @Autowired
    OrderRemarkService orderRemarkService;

    @Autowired
    OrderRemarkBService orderRemarkBService;

    @Autowired
    OrderDetailService orderDetailService;

    @Autowired
    OrderDiscountService orderDiscountService;

    @Autowired
    OrderServiceItemService orderServiceItemService;

    @Autowired
    OrderVisitService orderVisitService;

    @Autowired
    OrderPartService orderPartService;

    @Autowired
    OrderWarrantyService orderWarrantyService;

    @Autowired
    OrderWarrantyProductService orderWarrantyProductService;

    @Autowired
    OrderLogBService orderLogBService;

    @Autowired
    OrderChangeRecordService orderChangeRecordService;

    @Autowired
    OrderMemberService orderMemberService;

    @Autowired
    BaseCodeService baseCodeService;

    @Autowired
    OrderProductService orderProductService;

    @Autowired
    MasterWorkingService masterWorkingService;

    @Autowired
    OrderWorkRedistributeApplyService orderWorkRedistributeApplyService;

    @Autowired
    OrderCallRecordService orderCallRecordService;

    @Resource
    private RedisManager redisManager;

    @Autowired
    private MasterWorkService masterWorkService;

    @Autowired
    private OrderExtendService orderExtendService;

    @Autowired
    private OrderWorkListBService orderWorkListBService;

    @Autowired
    private OrderProductExtendBService orderProductExtendBService;

    @Autowired
    private OrderFactoryPartService orderFactoryPartService;

    @Autowired
    private OrderServiceItemBService orderServiceItemBService;

    @Autowired
    private OrderFactoryService orderFactoryService;

    @Autowired
    private OrderTmallExtendService orderTmallExtendService;

    @Autowired
    private OrderXnoBindService orderXnoBindService;

    @Autowired
    private OrderTrackService orderTrackService;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private OrderWarrantyBService orderWarrantyBService;

    @Autowired
    OrderAttachmentService orderAttachmentService;

    @Autowired
    OrderWorkEsBService orderWorkEsBService;

    @Autowired
    private OrderWorkERPQueryBService orderWorkERPQueryBService;

    @Autowired
    private OrderWorkProgrammeBService orderWorkProgrammeBService;

    @Autowired
    private OrderDiscountCalcBService orderDiscountCalcBService;

    @Autowired
    private OrderOperationService orderOperationService;
    @Autowired
    private MessageGetSendInfoService messageGetSendInfoService;

    @Autowired
    protected MessageWeChatTemplateService messageWeChatTemplateService;
    @Autowired
    private OrderTagService orderTagService;
    @Autowired
    private OrderWorkAcceptanceService orderWorkAcceptanceService;
    @Autowired
    private OrderStockBService orderStockBService;
    @Autowired
    private WorkTrackBService workTrackBService;
    @Autowired
    private ServItemBService servItemBService;
    @Autowired
    private OrderAcceptMaintainItemService orderAcceptMaintainItemService;
    @Autowired
    private OrderQuotationProcessService orderQuotationProcessService;
    @Autowired
    private WallQuotationService wallQuotationService;

    @Autowired
    private OrderAttachmentBService orderAttachmentBService;

    @Autowired
    private CancelApplyBService cancelApplyBService;

    @Autowired
    private AttachmentBService attachmentBService;

    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerListRemoteService engineerListRemoteService;

    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerTakeConfigListRemoteService engineerTakeConfigListRemoteService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private ChannelListRemoteService channelListRemoteService;

//    @Reference(version = com.zmn.mer.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
//    private FactoryListRemoteService factoryListRemoteService;

    @Reference(version = com.zmn.erp.dubbo.utils.DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerAccountRemoteService engineerAccountRemoteService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private CompanyListRemoteService companyListRemoteService;

/*    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION , check = false)
    private CoupRemoteService coupRemoteService;*/

    //@Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    //private EngineerTouchModifyRemoteService engineerTouchModifyRemoteService;

    @Autowired
    private MqProviderService mqProviderService;

   // @Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    //private RoleListRemoteService roleListRemoteService;

    @Reference(version = VasDubboConsts.INTERFACE_VERSION, check = false)
    private VasOrderListRemoteService vasOrderListRemoteService;

    @Reference(version = DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerSupervisorListRemoteService engineerSupervisorListRemoteService;

    @Reference(version = com.zmn.comment.dubbo.interfaces.utils.DubboConsts.INTERFACE_VERSION, check = false)
    private CmtCommentListRemoteService cmtCommentListRemoteService;
    @DubboReference(version = com.zmn.comment.dubbo.interfaces.utils.DubboConsts.INTERFACE_VERSION, check = false)
    private CmtCommentApiListRemoteService cmtCommentApiListRemoteService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private ItemTimeRemoteService itemTimeRemoteService;
    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private CategProductListRemoteService categProductListRemoteService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private PilotRemoteService pilotRemoteService;

    @Reference(version = com.zmn.performance.dubbo.consts.DubboConsts.INTERFACE_VERSION, check = false)
    ConfEngineerFiveListRemoteService confEngineerFiveListRemoteService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    StockListRemoteService stockListRemoteService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private CategServProductListRemoteService categServProductListRemoteService;

    @Reference(version = com.zmn.xno.common.constant.SystemConstants.DUBBO_CONSTS_INTERFACE_VERSION, check = false)
    private XnoRemoteService xnoRemoteService;

    @Reference(version = com.zmn.track.dubbo.consts.DubboConsts.INTERFACE_VERSION, check = false)
    private TrackWorkListRemoteService trackWorkListRemoteService;

    @Reference(version = com.zmn.base.plat.engine.common.constant.DubboConsts.INTERFACE_VERSION, check = false)
    private ItemPartsRemoteService itemPartsRemoteService;

    @DubboReference(version = com.zmn.base.sdss.dubbo.interfaces.consts.DubboConsts.INTERFACE_VERSION, check = false)
    private CompositeServeScoreForOmsListRemoteService compositeServeScoreForOmsListRemoteService;

    @Reference(version = com.zmn.track.dubbo.consts.DubboConsts.INTERFACE_VERSION, check = false)
    private OrderCancelApplyListRemoteService orderCancelApplyListRemoteService;

    @DubboReference(version = com.zmn.uuc.common.constant.DubboConsts.INTERFACE_VERSION,check = false)
    private UserThirdListRemoteService userThirdListRemoteService;

    @Resource
    private ConfOrderChannelBService confOrderChannelBService;

    @Resource
    private OrderPayDiscountService orderPayDiscountService;
    @Resource
    private OrderEncryptService orderEncryptService;

    @Resource
    private OrderFinalPriceQuotationBService orderFinalPriceQuotationBService;
    /************************************************************************************************/

    /**
     * 工程师接单
     *
     * @param masterTakeDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_TAKE, beforeProceed = false)
    public void updateMasterTake(MasterTakeDTO masterTakeDTO, OrderWork orderWork) throws OmsBaseException {
        log.info("{} 工程师领单", orderWork.getOrderId());
        // 工程师领单时 1.清洗单产生服务项目 2.厂商保内订单 产生远程费
        List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderWork.getOrderId());
        if (Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_REWORK) && CollectionUtil.isNotNullOrEmpty(orderServiceItemList)) {
            orderServiceItemService.deleteByOrderId(orderWork.getOrderId());
            orderServiceItemList = null;
        }

        if (CollectionUtil.isNullOrEmpty(orderServiceItemList)) {
            // 新增默认服务项
            orderServiceItemBService.createServiceItemByMasterTake(orderWork);
            // 插入了默认服务项，写入日志
            masterTakeDTO.setServiceItemLog(this.getServiceItemLog(orderWork.getOrderId()));
        }
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(masterTakeDTO.getOrderId());
        updateOrderWork.setWorkId(masterTakeDTO.getWorkId());
        updateOrderWork.setMasterId(masterTakeDTO.getMasterId());
        updateOrderWork.setStatus(OrderStatusConsts.WORK_STATUS_TAKE);
        updateOrderWork.setTakeTime(new Date());
        masterWorkService.updateMasterTake(updateOrderWork);

        // 修改进行中工单状态
        MasterWorking masterWorking = new MasterWorking();
        masterWorking.setWorkId(updateOrderWork.getWorkId());
        masterWorking.setStatus(updateOrderWork.getStatus());
        masterWorking.setTakeTime(updateOrderWork.getTakeTime());
        masterWorkingService.updateMasterWorking(masterWorking);
    }

    private String getServiceItemLog(Long orderId) {
        // 判断是否插入了默认服务项
        List<OrderServiceItem> newServiceItem = orderServiceItemService.listByOrderIdSrcMaster(orderId);
        if (CollectionUtil.isNullOrEmpty(newServiceItem)) {
            return null;
        }

        List<String> collect = newServiceItem.stream().map(OrderServiceItem::getServItemName).collect(Collectors.toList());
        int price = newServiceItem.stream().filter(e -> Objects.nonNull(e.getTotalPrice())).mapToInt(OrderServiceItem::getTotalPrice).sum();
        StringBuilder log = new StringBuilder("领单塞入默认服务项：");
        log.append("\n");
        log.append(StringUtils.join(collect, "，"));
        log.append("\n");
        log.append("金额：").append(MoneyUtil.parseToYuanEndWithUnit(price));
        return log.toString();
    }

    /**
     * 工程师出发
     *
     * @param masterLevaeDTO
     * @return
     * @throws Exception
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_MASTER_LEAVE)
    public boolean updateMasterLeave(MasterLeaveDTO masterLevaeDTO) throws OmsBaseException {
        OrderWork orderWork = orderWorkService.findMasterWorkDetail(masterLevaeDTO.getOrderId(),
                masterLevaeDTO.getWorkId(), masterLevaeDTO.getMasterId());
        if (orderWork == null) {
            throw new OmsBaseException(OrderFailConsts.FAIL_DATA_CHANGE_ORDER_NOMASTER, "无效的工单");
        }

        /*（1）渠道ID：31055，渠道名称：战略渠道F3（天猫B端安装）（2）渠道ID：34958，渠道名称：天猫欧派
        距离预约时间小于等于2小时：可以操作上门 ;距离预约时间大于2小时：不可以操作上门 */
        if (orderWork.getPlatWork().equals(com.zmn.consts.GlobalConsts.PLAT_MARK_YEYX)) {
            Integer channelId = orderWork.getChannelId();
            if (Objects.equals(channelId, OrderConsts.CHANNEL_ID_TMALL_BUSINESS)
                    || Objects.equals(channelId, OrderConsts.CHANNEL_ID_TMALL_BIZ_OPPEIN)
                    || Objects.equals(channelId, OrderConsts.CHANNEL_ID_TMALL_BIZ_LAIMD)) {
                long timespan = DateUtil.getTimespan(orderWork.getDutyTime(), DateUtil.addMinute(DateUtil.getNow(), 120), DateUtil.UNIT_SECOND);
                if (timespan < 0) {
                    throw new OmsBaseException("该渠道距离预约时间大于2小时，不允许操作上门，请修改预约时间");
                }
            }
        }

        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(masterLevaeDTO.getOrderId());
        updateOrderWork.setWorkId(masterLevaeDTO.getWorkId());
        updateOrderWork.setMasterId(masterLevaeDTO.getMasterId());
        updateOrderWork.setIsLeave(2);  //1未出发  2已出发

        // 修改师傅出发状态
        masterWorkService.updateMasterLeave(updateOrderWork);
        return true;
    }

    /**
     * 工程师上门
     *
     * @param visitDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_VISIT)
    public MasterVisitResponseDTO updateMasterVisit(MasterVisitDTO visitDTO, OrderWork orderWork)
            throws OmsBaseException {
        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            throw new OmsBaseException("工单不在进行中");
        }

        if (Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_VISIT)) {
            MasterVisitResponseDTO visitResponseDTO = new MasterVisitResponseDTO();
            visitResponseDTO.setSendNotify(false);
            visitResponseDTO.setVisitStatus(MasterConsts.VISIT_STATUS_SUCCESS);
            visitResponseDTO.setAlertMsg("准时上门，赞！");

            return visitResponseDTO;
        }

        if (Objects.equals(GlobalConsts.YES, visitDTO.getTmallFlag())) {
            if (!Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_TAKE) && !Objects
                    .equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_DISTRIBUTE)) {
                throw new OmsBaseException("勤鸽订单【已派单/已接单】状态才能上门");
            }
        } else {
            if (!Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_TAKE)) {
                throw new OmsBaseException("已接单状态才能上门");
            }
        }

        // 操作状态
        int visitStatus = MasterConsts.VISIT_STATUS_SUCCESS;
        // 提示信息
        String alertMsg = "准时上门，赞！";

        // 是否跳过预约时间校验
        if (!visitDTO.getSkipVerify()) {

            // 判断上门时间
            Date curTime = new Date();
            // 预约时间前2小时
            Date dutyTimeStart = new Date(orderWork.getDutyTime().getTime() - 120 * 60 * 1000);
            // 预约时间后2小时
            Date dutyTimeEnd = new Date(orderWork.getDutyTime().getTime() + 120 * 60 * 1000);

            // 1、F-保内订单，上门时不限制时间 2、C-保外订单，需2小时内才可上门
            if (Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_C)) {
                // 上门时间小于预约时间前二小时
                if (curTime.getTime() < dutyTimeStart.getTime()) {
                    // 预约时间是当天
                    if (DateUtil.getDateStart(curTime).getTime() == DateUtil.getDateStart(orderWork.getDutyTime()).getTime()) {
                        alertMsg = String.format("请在%s ~ %s上门 ", DateUtil.toString(dutyTimeStart, "HH时mm分"), DateUtil.toString(orderWork.getDutyTime(), "HH时mm分"));
                    } else {
                        alertMsg = String.format("请在%s，%s左右上门", DateUtil.getDateStr(orderWork.getDutyTime(), curTime),
                                DateUtil.toString(orderWork.getDutyTime(), "HH时mm分"));
                    }
                    throw new OmsBaseException(alertMsg);
                } else if (curTime.getTime() > dutyTimeEnd.getTime()) {
                    // 上门超时
                    visitStatus = MasterConsts.VISIT_STATUS_OVERTIME;
                    alertMsg = "上门超过2小时，下次记得准时哦！";
                }
            }
        }

        MasterVisitResponseDTO visitResponseDTO = new MasterVisitResponseDTO();
        visitResponseDTO.setSendNotify(true);
        visitResponseDTO.setVisitStatus(visitStatus);
        visitResponseDTO.setAlertMsg(alertMsg);

        // 更新上门状态
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(visitDTO.getOrderId());
        updateOrderWork.setWorkId(visitDTO.getWorkId());
        updateOrderWork.setMasterId(visitDTO.getMasterId());
        updateOrderWork.setStatus(OrderStatusConsts.WORK_STATUS_VISIT);
        updateOrderWork.setVisitTime(new Date());
        masterWorkService.updateMasterVisit(updateOrderWork);

        // 修改进行中工单状态
        MasterWorking masterWorking = new MasterWorking();
        masterWorking.setWorkId(updateOrderWork.getWorkId());
        masterWorking.setStatus(updateOrderWork.getStatus());
        masterWorking.setVisitTime(updateOrderWork.getVisitTime());
        masterWorkingService.updateMasterWorking(masterWorking);

        // 一口价订单初始化报价流程信息
        OrderFinalPriceQuotationDataDIO dataDIO = new OrderFinalPriceQuotationDataDIO();
        dataDIO.setOrderId(orderWork.getOrderId());
        dataDIO.setWorkId(orderWork.getWorkId());
        dataDIO.setFinalPrice(orderWork.getFinalPrice());
        dataDIO.setProductId(orderWork.getProductId());
        dataDIO.setOperator("系统");
        orderFinalPriceQuotationBService.initOrderFinalPriceQuotationData(dataDIO);
        return visitResponseDTO;
    }

    /**
     * 改价格
     *
     * @param changePriceDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_MASTER_CHANGE_PRICE)
    public void updatePrice(ChangePriceDTO changePriceDTO) throws OmsBaseException {
        OrderWork orderWork = orderWorkService
                .findMasterWorkDetail(changePriceDTO.getOrderId(), changePriceDTO.getWorkId(),
                        changePriceDTO.getMasterId());
        if (orderWork == null) {
            throw new OmsBaseException("无效的工单");
        }

        if (Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_COMPLETE) || !Objects
                .equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            throw new OmsBaseException("工单不在进行中");
        }

        // 预付款
        int prepayAmount = orderWork.getPrepayAmount() == null ? 0 : orderWork.getPrepayAmount();
        // 渠道预付款
        int channelPrepayAmount = orderWork.getChannelPrepayAmount() == null ? 0 : orderWork.getChannelPrepayAmount();
        // 定金
        int depositAmount = orderWork.getDepositAmount() == null ? 0 : orderWork.getDepositAmount();
        // 优惠金额
        int discountAmount = orderWork.getDiscountAmount() == null ? 0 : orderWork.getDiscountAmount();
        // 已支付总金额
        int paidAmount = prepayAmount + channelPrepayAmount + depositAmount + discountAmount;

        if (changePriceDTO.getPrice() < paidAmount) {
            BigDecimal bd = AmountUtil.fen2Yuan(paidAmount);
            throw new OmsBaseException(String.format("工单金额不能小于%.2f元", bd.doubleValue()));
        }

        WorkUpdateAmountDTO updateAmountDTO = new WorkUpdateAmountDTO();
        updateAmountDTO.setOrderId(changePriceDTO.getOrderId());
        updateAmountDTO.setWorkId(changePriceDTO.getWorkId());
        updateAmountDTO.setOriginalAmount(changePriceDTO.getPrice());
        updateAmountDTO.setOnlyVisit(changePriceDTO.getOnlyVisit());
        orderWorkAmountBService.updateOriginalAmount(updateAmountDTO);
    }

    /**
     * 标记为使用配件
     *
     * @param usePartDTO
     */
    @Override
    public void updateUsePart(UsePartDTO usePartDTO) throws OmsBaseException {
        OrderWork orderWork = orderWorkService
                .findMasterWorkDetail(usePartDTO.getOrderId(), usePartDTO.getWorkId(), usePartDTO.getMasterId());
        if (orderWork == null) {
            throw new OmsBaseException("无效的工单");
        }

        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            throw new OmsBaseException("此工单已收单，不可操作配件");
        }

        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(usePartDTO.getOrderId());
        updateOrderWork.setWorkId(usePartDTO.getWorkId());
        updateOrderWork.setMasterId(usePartDTO.getMasterId());
        updateOrderWork.setPartUse(GlobalConsts.YES);
        updateOrderWork.setPartRetain(GlobalConsts.NONE);
        masterWorkService.updateUsePart(updateOrderWork);
    }

    /**
     * 纸质保修卡
     *
     * @param manualCodeDTO
     */
    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_MANUALCODE)
    public void updateManualCode(ManualCodeDTO manualCodeDTO) throws OmsBaseException {
        OrderWork orderWork = orderWorkService
                .findMasterWorkDetail(manualCodeDTO.getOrderId(), manualCodeDTO.getWorkId(),
                        manualCodeDTO.getMasterId());
        if (orderWork == null) {
            throw new OmsBaseException(OrderFailConsts.FAIL_DATA_CHANGE_ORDER_NOMASTER, "无效的工单");
        }

        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            throw new OmsBaseException(OrderFailConsts.FAIL_DATA_CHANGE_ORDER_STATUS, "工单不在进行中");
        }

        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(manualCodeDTO.getOrderId());
        updateOrderWork.setWorkId(manualCodeDTO.getWorkId());
        updateOrderWork.setMasterId(manualCodeDTO.getMasterId());
        updateOrderWork.setManualCode(manualCodeDTO.getManualCode());
        masterWorkService.updateManualCode(updateOrderWork);
    }

    /**
     * 工程师备注
     *
     * @param masterRemarkDTO
     */
    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_MASTER_REMARK)
    public void updateMasterRemark(MasterRemarkDTO masterRemarkDTO) throws OmsBaseException {
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(masterRemarkDTO.getOrderId());
        updateOrderWork.setWorkId(masterRemarkDTO.getWorkId());
        updateOrderWork.setMasterId(masterRemarkDTO.getMasterId());
        updateOrderWork.setMasterRemark(masterRemarkDTO.getRemark());
        updateOrderWork.setCurrentRemark(masterRemarkDTO.getRemark());
        masterWorkService.updateMasterRemark(updateOrderWork);
    }

    /**
     * 发票信息
     *
     * @param masterRemarkDTO
     */
    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_MASTER_INVOICE)
    public void updateInvoiceInfo(MasterRemarkDTO masterRemarkDTO) throws OmsBaseException {

    }

    /**
     * 发票图片
     *
     * @param masterRemarkDTO
     */
    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_MASTER_INVOICE_PIC)
    public void updateInvoicePic(MasterRemarkDTO masterRemarkDTO) throws OmsBaseException {

    }

    /**
     * 贴花照片
     *
     * @param orderImageDTO
     */
    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_APPLIQUE_IMAGE, beforeProceed = false)
    public void updateAppliqueImage(OrderImageDTO orderImageDTO) throws OmsBaseException {
        OrderWork orderWork = orderWorkService
                .findMasterWorkDetail(orderImageDTO.getOrderId(), orderImageDTO.getWorkId(),
                        orderImageDTO.getMasterId());
        if (orderWork == null) {
            throw new OmsBaseException("无效的工单");
        }

        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            throw new OmsBaseException("工单不在进行中");
        }

        OrderExtend dbOrderExtend = orderExtendService.findOrderExtendByOrderId(orderImageDTO.getOrderId());
        String oldUrls = dbOrderExtend != null ? dbOrderExtend.getAppliqueSrc() : null;
        // 得到新的照片地址
        String newUrls = this.convertUrls(oldUrls, orderImageDTO.getUrl(), orderImageDTO.getOpType(), orderImageDTO.getIndex());

        // 更新贴花照片
        OrderExtend orderExtend = new OrderExtend();
        orderExtend.setExtId(orderImageDTO.getOrderId());
        orderExtend.setAppliqueSrc(newUrls);
        orderExtendService.updateOrderExtend(orderExtend);

        // 更新贴花照片
        OrderImageDTO orderImage = BeanMapper.map(orderImageDTO, OrderImageDTO.class);
        orderImage.setUrl(newUrls);
        orderAttachmentBService.modifyOrderWorkAttachment(orderImage, orderWork);
    }

    /**
     * 工单照片
     *
     * @param orderImageDTO
     */
    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_ORDER_IMAGE)
    public void updateOrderImage(OrderImageDTO orderImageDTO) throws OmsBaseException {
        OrderWork orderWork = orderWorkService
                .findMasterWorkDetail(orderImageDTO.getOrderId(), orderImageDTO.getWorkId(),
                        orderImageDTO.getMasterId());
        if (orderWork == null) {
            throw new OmsBaseException("无效的工单");
        }

        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            throw new OmsBaseException("工单不在进行中");
        }

        OrderExtend dbOrderExtend = orderExtendService.findOrderExtendByOrderId(orderImageDTO.getOrderId());
        String oldUrls = dbOrderExtend != null ? dbOrderExtend.getImageSrc() : null;
        // 得到新的照片地址
        String newUrls = this
                .convertUrls(oldUrls, orderImageDTO.getUrl(), orderImageDTO.getOpType(), orderImageDTO.getIndex());

        // 更新工单照片
        OrderExtend orderExtend = new OrderExtend();
        orderExtend.setExtId(orderImageDTO.getOrderId());
        orderExtend.setImageSrc(newUrls);
        orderExtendService.updateOrderExtend(orderExtend);
    }

    /**
     * 工单工程师照片
     *
     * @param orderImageDTO
     */
    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_MASTER_IMAGE, beforeProceed = false)
    public void updateMasterImage(OrderImageDTO orderImageDTO) throws OmsBaseException {
        OrderWork orderWork = orderWorkService
                .findMasterWorkDetail(orderImageDTO.getOrderId(), orderImageDTO.getWorkId(),
                        orderImageDTO.getMasterId());
        if (orderWork == null) {
            throw new OmsBaseException("无效的工单");
        }

        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            throw new OmsBaseException("工单不在进行中");
        }

        OrderExtend dbOrderExtend = orderExtendService.findOrderExtendByOrderId(orderImageDTO.getOrderId());
        String oldUrls = dbOrderExtend != null ? dbOrderExtend.getMasterSrc() : null;
        // 得到新的照片地址
        String newUrls = this
                .convertUrls(oldUrls, orderImageDTO.getUrl(), orderImageDTO.getOpType(), orderImageDTO.getIndex());

        // 更新工程师照片
        OrderExtend orderExtend = new OrderExtend();
        orderExtend.setExtId(orderImageDTO.getOrderId());
        orderExtend.setMasterSrc(newUrls);
        orderExtendService.updateOrderExtend(orderExtend);


        // 发送自动审核信息
        if (Objects.equals(orderImageDTO.getOpType(), OrderConsts.ORDER_IMAGE_UPDATE)) {
//            orderPhotoBService.sendImageDetectionMessage(orderWork.getOrderId(), orderWork.getWorkId(), OrderAttachmentTypeEnum.XXZ.getCode());
        }
    }

    /**
     * 照片地址转换
     *
     * @param oldUrls 原有地址，逗号分割
     * @param newUrl  新的地址
     * @param opType  操作类型：1 更新 ，2 删除
     * @param index   下标（第几张照片） 从 0 开始
     * @return 逗号分割的照片地址
     */
    @Override
    public String convertUrls(String oldUrls, String newUrl, Integer opType, Integer index) {
        // 原有照片，放入map中
        Map<Integer, String> imgMap = new LinkedHashMap<Integer, String>();
        if (StringUtils.isNotBlank(oldUrls)) {
            String[] arr = oldUrls.split(",");
            for (int i = 0; i < arr.length; i++) {
                imgMap.put(i, arr[i]);
            }
        }

        String urls = "";// 逗号分割的多个照片地址

        switch (opType) {
            case OrderConsts.ORDER_IMAGE_UPDATE: // 更新照片操作
                imgMap.put(imgMap.size(), newUrl);
                urls = StringUtils.join(imgMap.values(), ",");
                break;
            case OrderConsts.ORDER_IMAGE_DELETE: // 删除照片操作
                imgMap.remove(index);
                if (imgMap.size() > 0) {
                    urls = StringUtils.join(imgMap.values(), ",");
                }
                break;
            default:
                break;
        }

        return urls;
    }

    /**
     * 检查工程师是否有未算账工单
     *
     * @param masterId
     */
    @Override
    public boolean checkWorkStatus(Integer masterId, Date startTime, Date endTime) {

        MasterWorkStatusDTO masterWorkStatus = this.getMasterWorkStatus(masterId, startTime, endTime);
        if (masterWorkStatus.isHasDoingOrderWork()) {
            return true;
        } else {
            return masterWorkStatus.isHasUnAccountOrderWork();
        }
    }

    /**
     * 检查工程师是否有未算账工单(区分返回)
     *
     * @param masterId
     */
    @Override
    public MasterWorkStatusDTO getMasterWorkStatus(Integer masterId, Date startTime, Date endTime) {
        String dutyTime = null;
        // 预约时间
        if (startTime != null && endTime != null) {
            String startTimeStr = DateUtil.toString(startTime, DateUtil.FORMAT_DEFAULT);
            String endTimeStr = DateUtil.toString(endTime, DateUtil.FORMAT_DEFAULT);
            dutyTime = startTimeStr + "," + endTimeStr;
        }

        // 进行中的工单
        OrderWorkQuery doingOrderQuery = new OrderWorkQuery();
        doingOrderQuery.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK));
        doingOrderQuery.setMasterId(masterId);
        doingOrderQuery.setDutyTime(dutyTime);
        // 已派单 已领单 已上门 已完成 --- 进行中
        doingOrderQuery.setWorkStatus(Arrays.asList(OrderStatusConsts.WORK_STATUS_DISTRIBUTE, OrderStatusConsts.WORK_STATUS_TAKE,
                OrderStatusConsts.WORK_STATUS_VISIT, OrderStatusConsts.WORK_STATUS_SERVICE_COMPLETE, OrderStatusConsts.WORK_STATUS_COMPLETE));
        doingOrderQuery.setWorkResultStatusList(Arrays.asList(OrderStatusConsts.WORK_RESULT_DOING));
        Integer count = orderWorkListBService.countOrderWorkByQuery(doingOrderQuery);
        MasterWorkStatusDTO masterWorkStatusDTO = new MasterWorkStatusDTO();
        masterWorkStatusDTO.setHasDoingOrderWork(count > 0);

        // 进行中的多工程师订单
        OrderWorkQuery multiMasterQuery = new OrderWorkQuery();
        multiMasterQuery.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK));
        multiMasterQuery.setMultiMasterId(masterId);
        multiMasterQuery.setMultiMaster(GlobalConsts.YES);
        multiMasterQuery.setDutyTime(dutyTime);
        multiMasterQuery.setWorkStatus(Arrays.asList(OrderStatusConsts.WORK_STATUS_DISTRIBUTE, OrderStatusConsts.WORK_STATUS_TAKE,
                OrderStatusConsts.WORK_STATUS_VISIT, OrderStatusConsts.WORK_STATUS_SERVICE_COMPLETE, OrderStatusConsts.WORK_STATUS_COMPLETE));
        multiMasterQuery.setWorkResultStatusList(Arrays.asList(OrderStatusConsts.WORK_RESULT_DOING));
        count = orderWorkListBService.countOrderWorkByQuery(multiMasterQuery);
        masterWorkStatusDTO.setHasMultiMasterDoingOrderWork(count > 0);

        // 未算账订单
        OrderWorkQuery checkOutQuery = new OrderWorkQuery();
        checkOutQuery.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK));
        checkOutQuery.setMasterId(masterId);
        checkOutQuery.setDutyTime(dutyTime);
        checkOutQuery.setWorkStatus(Arrays.asList(OrderStatusConsts.WORK_STATUS_CHECKOUT));
        count = orderWorkListBService.countOrderWorkByQuery(checkOutQuery);
        masterWorkStatusDTO.setHasUnAccountOrderWork(count > 0);

        // 多工程师未算账订单
        OrderWorkQuery checkOutMultiMasterQuery = new OrderWorkQuery();
        checkOutMultiMasterQuery.setWorkType(Arrays.asList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK));
        checkOutMultiMasterQuery.setMultiMasterId(masterId);
        checkOutMultiMasterQuery.setMultiMaster(GlobalConsts.YES);
        checkOutMultiMasterQuery.setDutyTime(dutyTime);
        checkOutMultiMasterQuery.setWorkStatus(Arrays.asList(OrderStatusConsts.WORK_STATUS_CHECKOUT));
        count = orderWorkListBService.countOrderWorkByQuery(checkOutMultiMasterQuery);
        masterWorkStatusDTO.setHasMultiMasterUnAccountOrderWork(count > 0);

        return masterWorkStatusDTO;
    }

    /**
     * 进行中工单
     *
     * @param masterId
     */
    @Override
    public WorkListDTO listDoingWorkByQuery(Integer masterId, String queryText) throws OmsBaseException {
        log.debug("搜索师傅进行中工单 masterId: {}, queryText={}", masterId, queryText);
        Objects.requireNonNull(masterId, "工程师ID不能为空");
        if (StringUtils.isBlank(queryText)) {
            return new WorkListDTO();
        }

        int length = queryText.length();
        if (length > 20) {
            queryText = queryText.substring(0, 20);
        }

        queryText = queryText.replace("*", "");

        BoolQueryBuilder boolQueryBuilder = boolQuery();
        BoolQueryBuilder shouldBoolQueryBuilder = boolQuery();

        boolean isNumber = NumberUtil.isNumber(queryText);
        if (isNumber) {
            // 工单号查询
            if (length >= 18) {
                shouldBoolQueryBuilder.should(QueryBuilders.termQuery("id", queryText));
            } else if (length == 6) {
                shouldBoolQueryBuilder.should(QueryBuilders.termQuery("codeEnd6", queryText));
            }

            // 手机号查询
            if (length >= 7) {
                shouldBoolQueryBuilder.should(QueryBuilders.termQuery("contact.phone", orderEncryptService.encrypt(queryText)));
                shouldBoolQueryBuilder.should(QueryBuilders.termQuery("contact.bindPhone", queryText));
            } else if (length == 4) {
                shouldBoolQueryBuilder.should(QueryBuilders.termQuery("contact.phoneEnd4", queryText));
            }
        }

        // shouldBoolQueryBuilder.should(QueryBuilders.wildcardQuery("contact.queryFullAddress", String.format("*%s*", queryText)));
        shouldBoolQueryBuilder.should(QueryBuilders.termQuery("contact.contactName", queryText));
        shouldBoolQueryBuilder.should(QueryBuilders.termQuery("contact.userName", queryText));

        // 获取产品二级分类id
        try {
            CategProductQuery categoryDIO = new CategProductQuery();
            categoryDIO.setCategName(queryText);
            categoryDIO.setLevel(GlobalConsts.LEVEL_2);
            ResponseDTO<List<CategProductDRO>> listResponseDTO = categProductListRemoteService.listByQuery(categoryDIO);
            log.debug("搜索师傅进行中工单-获取产品二级分类 categoryDIO: {}, listResponseDTO={}", categoryDIO, listResponseDTO);
            List<CategProductDRO> categoryDROList = listResponseDTO.getData();
            if (CollectionUtil.isNotNullOrEmpty(categoryDROList)) {
                List<Integer> categIdList = categoryDROList.stream().map(CategProductDRO::getCategId).collect(Collectors.toList());
                shouldBoolQueryBuilder.should(QueryBuilders.termsQuery("categTwoId", categIdList));
                shouldBoolQueryBuilder.should(QueryBuilders.termsQuery("showCategTwoId", categIdList));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        BoolQueryBuilder filter = boolQuery()
                .filter(QueryBuilders.termQuery("masterId", masterId))
                .filter(boolQueryBuilder.must(QueryBuilders.termsQuery("resultStatus", Lists.newArrayList(OrderStatusConsts.WORK_RESULT_DOING)))
                        .must(QueryBuilders.termsQuery("status", Lists.newArrayList(OrderStatusConsts.WORK_STATUS_TAKE, OrderStatusConsts.WORK_STATUS_VISIT)))
                        .must(shouldBoolQueryBuilder)
                );

        NativeSearchQuery build = new NativeSearchQueryBuilder()
                .withPageable(Pageable.unpaged())
                .withFields("id")
                .withQuery(filter)
                .build();

        log.debug("搜索师傅进行中工单 masterId: {}, queryText={}, esQuery:{}", masterId, filter.toString());

        List<EsOrderWork> content = orderWorkEsBService.listPageByQuery(build);
        if (CollectionUtils.isEmpty(content)) {
            return new WorkListDTO();
        }

        // 查询工程师工单
        List<Long> workIdList = content.stream().map(EsOrderWork::getId).collect(Collectors.toList());
        List<MasterWorking> orderWorkList = masterWorkingService.listMasterWorkingByWorkIdList(workIdList);
        WorkListDTO workListDTO = this.listMasterOrderWork(orderWorkList);
        return workListDTO;
    }

    /**
     * 进行中工单
     *
     * @param masterId
     */
    @Override
    public WorkListDTO getWorkingList(Integer masterId) throws OmsBaseException {
        log.debug("【{}】进行中工单查询入参", JSON.toJSONString(masterId));
        List<MasterWorking> orderWorkList = masterWorkingService.listMasterWorkingByMasterId(masterId);

        // 过滤改派中工单
        orderWorkList.removeIf(work -> Objects.equals(work.getRedistributeStatus(), MasterWorkConsts.REDISTRIBUTE_STATUS_ING));

        // 查询工程师工单

        log.debug("orderWorkList={}", orderWorkList);
        WorkListDTO workListDTO = this.listMasterOrderWork(orderWorkList);

        // 生成版本号并调用工程师dubbo服务保存到redis
        String version = getVersion(workListDTO);

        //engineerTouchModifyRemoteService.saveEngineerWorkVersion(masterId, version);
        mqProviderService.sendEngineerWorkVersion(masterId, version);
        workListDTO.setVersion(version);

        return workListDTO;
    }

    @Override
    public List<WorkRedistributeListItemDTO> getRedistributingList(Integer masterId) throws OmsBaseException {

        MasterWorkingQuery query = new MasterWorkingQuery();
        query.setMasterId(masterId);
        query.setRedistributeStatus(MasterWorkConsts.REDISTRIBUTE_STATUS_ING);
        List<MasterWorking> orderWorkList = masterWorkingService.listMasterWorkingByQuery(query);

        if (CollectionUtil.isNullOrEmpty(orderWorkList)) {
            return Lists.newArrayList();
        }

        // 查询工程师工单
        List<WorkRedistributeListItemDTO> workList = Lists.newArrayList();

//        // 生成版本号并调用工程师dubbo服务保存到redis
//        String version = getVersion(workListDTO);

        // 查询进行中的改派申请
        List<Long> orderIdList = orderWorkList.stream().map(MasterWorking::getWorkId).collect(Collectors.toList());

        List<OrderWorkRedistributeApply> applyList = orderWorkRedistributeApplyService.listByOrderIdListAndRedistributeStatus(orderIdList, RedistributeStatusEnum.WAIT_REDISTRIBUTE.getCode());
        Map<Long, OrderWorkRedistributeApply> applyMap = applyList.stream().collect(Collectors.toMap(OrderWorkRedistributeApply::getOrderId, Function.identity(), (e1, e2) -> e1));

        log.debug("改派信息：{}", JSON.toJSONString(applyList));

        // 转化数据
        orderWorkList.stream().forEach(orderWork -> {
            WorkRedistributeListItemDTO item = BeanMapper.map(orderWork, WorkRedistributeListItemDTO.class);

            WorkProgrammeDTO programme = new WorkProgrammeDTO();
            programme.setProgrammeStatus("处理中");
            programme.setOperateText("撤销");
            item.setProgramme(programme);

            item.setOrderId(item.getWorkId());

            OrderWorkRedistributeApply apply = applyMap.get(orderWork.getWorkId());
            if (Objects.nonNull(apply)) {
                item.setRedistributeId(apply.getRedistributeId());
                item.setDutyTime(apply.getDutyTime());
                item.setRedistributeReason(apply.getReason());
                item.setApplyRemark(apply.getApplyRemark());
            }

            workList.add(item);
        });


        return workList;
    }

    /**
     * 查询工程师工单 From DB
     *
     * @param orderWorkList
     */
    private WorkListDTO listMasterOrderWork(List<MasterWorking> orderWorkList) throws OmsBaseException {
        WorkListDTO workListDTO = new WorkListDTO();

        // 去掉高等级工程师的设置，谢文兵 2022.09.27
        // 产品分组id集合
        // Set<Integer> setProductGroupId = new HashSet<>(orderWorkList.size());
        // List<EngineerProductGroupCompositeScoreForDispatchOrderDRO> compositeScoreList = null;

        Integer masterId = 0;
        Integer cityId = 0;

        // es工单信息
        Map<Long, MasterDoingOrderWorkDRO> doingWorkMap = new HashMap<>();

        if (CollectionUtil.isNotNullOrEmpty(orderWorkList)) {
            List<Long> orderIds = orderWorkList.stream()
                    .map(MasterWorking::getWorkId)
                    .collect(Collectors.toList());
            OrderWorkQuery orderWorkQuery = new OrderWorkQuery();
            orderWorkQuery.setOrderIdList(orderIds);
            orderWorkQuery.setPageSize(orderIds.size() + 1);
            orderWorkQuery.setIncludes(Stream.of(MasterDoingOrderWorkDRO.class.getDeclaredFields())
                    .map(Field::getName)
                    .collect(Collectors.toList()));
            List<EsOrderWork> esOrderWorks = orderWorkListBService.listPageOrderWorkByQuery(orderWorkQuery);
            List<MasterDoingOrderWorkDRO> doingOrderWorkDROS = BeanMapper.mapList(esOrderWorks, MasterDoingOrderWorkDRO.class);
            doingWorkMap = doingOrderWorkDROS.stream()
                    .collect(Collectors.toMap(MasterDoingOrderWorkDRO::getId, esOrderWork -> esOrderWork, (entity1, entity2) -> entity1));

            for(MasterDoingOrderWorkDRO doingOrderWorkDRO : doingOrderWorkDROS) {

                masterId = NumberUtil.isNullOrZero(masterId) ? doingOrderWorkDRO.getMasterId() : masterId;
                cityId = NumberUtil.isNullOrZero(cityId) ?  doingOrderWorkDRO.getCityId() : cityId;

                // 去掉高等级工程师的设置，谢文兵 2022.09.27
                // setProductGroupId.add(doingOrderWorkDRO.getServProductGroupId());
            }

            // 去掉高等级工程师的设置，谢文兵 2022.09.27
//            if (CollectionUtil.isNotNullOrEmpty(setProductGroupId)) {
//
//                List<Integer> productGroupIds = new ArrayList<>(setProductGroupId.size());
//                productGroupIds.addAll(setProductGroupId);
//                compositeScoreList = this.getHighLevelEngineer(masterId, productGroupIds, cityId);
//            }
        }

        //查询申请取消工单信息
        Map<Long, List<OrderCancelApplyDRO>> cancelApplyMap = this.getWorkCancelApplyMap(orderWorkList);

        List<WorkListItemDTO> dtoList = Lists.newArrayList();
        Map<Integer, Integer> vipChannelCache = Maps.newHashMap();
        Map<Integer, ConfOrderChannelDRO> channelConfCache = Maps.newHashMap();
        for (MasterWorking working : orderWorkList) {
            WorkListItemDTO dto = BeanMapper.map(working, WorkListItemDTO.class);

            dto.setOrderId(working.getWorkId());
            dto.setResultStatus(OrderStatusConsts.WORK_RESULT_DOING);

            MasterDoingOrderWorkDRO esOrderWork = doingWorkMap.get(working.getWorkId());
            dto.setMultipleAmount(GlobalConsts.NO);
            dto.setShowDeposit(GlobalConsts.YES);
            dto.setMultipleVisitStatus(GlobalConsts.NONE);
            if (Objects.nonNull(esOrderWork)) {

                List<EsOrderWorkProduct> productList = esOrderWork.getProductList();
                if (CollectionUtils.isNotEmpty(productList)) {
                    EsOrderWorkProduct esOrderWorkProduct = productList.get(0);
                    String productName = StringUtil.isBlank(esOrderWorkProduct.getProductName()) ? esOrderWorkProduct.getShowProductName() : esOrderWorkProduct.getProductName();
                    dto.setProductInfo(String.format("%s-%s*%s", StringUtils.defaultString(esOrderWorkProduct.getBrandName()), productName, esOrderWorkProduct.getNumber()));
                }

                List<OrderCancelApplyDRO> orderCancelApplyDROS = cancelApplyMap.get(working.getWorkId());
                if (Objects.equals(working.getWaitCancel(), GlobalConsts.YES)) {
                    // 获取取消时间
                    String cancelApplyDate = this.getCancelApplyDate(dto.getWorkId(), cancelApplyMap);
                    dto.setShowTime(cancelApplyDate);

                    // 获取取消缘由
                    String cancelApplyReason = this.getCancelApplyReason(dto.getWorkId(), cancelApplyMap);
                    dto.setShowText(cancelApplyReason);

                    orderCancelApplyDROS = Optional.ofNullable(orderCancelApplyDROS).orElse(Collections.EMPTY_LIST);
                    boolean isMasterReview = orderCancelApplyDROS.stream()
                            .anyMatch(e -> Objects.equals(e.getReviewUserType(), GlobalConsts.OPERATE_USER_TYPE_MASTER));
                    if (isMasterReview) {
                        dto.setCancelApplyUserType(GlobalConsts.OPERATE_USER_TYPE_USER);
                    } else if (CollectionUtil.isNotNullOrEmpty(esOrderWork.getWorkTrackList())) {
                        // 判断取消人 是 用户或者客服发起跟单
                        int waitCancelStatus = workTrackBService.getMasterWaitCancelStatus(esOrderWork.getWorkTrackList());
                        if (Objects.equals(waitCancelStatus, GlobalConsts.YES)) {
                            dto.setCancelApplyUserType(GlobalConsts.OPERATE_USER_TYPE_USER);
                        }
                    }
                }

                if (Objects.nonNull(esOrderWork.getContact())) {
                    // 街道
                    dto.setStreet(esOrderWork.getContact().getStreet());
                }

                // 是否需要发起收款--多次上门
                // 当前上门状态是已上门、工单金额不是0、服务分类是防水补漏和墙面翻新
                if (Objects.equals(esOrderWork.getStatus(), OrderStatusConsts.WORK_STATUS_VISIT)
                        && NumberUtil.isNotNullOrZero(esOrderWork.getOriginalAmount())
                        && (Objects.equals(esOrderWork.getServCategId(), ProductConsts.SERV_CATEG_WATERPROOF)
                        || Objects.equals(esOrderWork.getServCategId(), ProductConsts.SERV_CATEG_METOPE)
                        || Objects.equals(esOrderWork.getServCategId(), ProductConsts.SERV_CATEG_KITCHEN_TOILET))) {
                    dto.setMultipleAmount(GlobalConsts.YES);
                }

                List<EsOrderVisit> esOrderVisitList = esOrderWork.getOrderVisitList();
                if (CollectionUtil.isNotNullOrEmpty(esOrderVisitList)) {

                    boolean isDeposit = esOrderVisitList.stream()
                            .anyMatch(e -> Objects.equals(e.getMasterId(), esOrderWork.getMasterId())
                                    && !Objects.equals(e.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_CANCEL)
                                    && Objects.equals(e.getAmountType(), OrderPayConsts.ORDER_PAY_DEPOSIT));
                    if (isDeposit) {
                        dto.setShowDeposit(GlobalConsts.NO);
                    }

                    EsOrderVisit esOrderVisit = Streams.findLast(esOrderVisitList.stream()
                                    .filter(item -> Objects.equals(item.getMasterId(), working.getMasterId())
                                            && !Objects.equals(item.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_CANCEL)))
                            .orElse(null);
                    if (Objects.nonNull(esOrderVisit)) {
                        dto.setDutyTime(esOrderVisit.getExpectVisitTime());
                        dto.setMultipleVisitStatus(esOrderVisit.getVisitStatus());
                        if (NumberUtil.isNullOrZero(esOrderVisit.getOrderPayId())
                                && NumberUtil.isNullOrZero(esOrderVisit.getAcceptanceId())) {
                            dto.setMultiplePayStatus(PayConsts.PAY_STATUS_DONE);
                        } else {
                            dto.setMultiplePayStatus(esOrderVisit.getPayStatus());
                        }
                    }
                }

                // 是否剔除绩效
                log.debug("工单[{}] list:{}", dto.getOrderId(), JSON.toJSONString(esOrderWork.getOrderTagList()));
                boolean isExcludePerformace = Optional.ofNullable(esOrderWork.getOrderTagList()).orElse(Lists.newArrayList()).stream().anyMatch(tag -> {
                    if (CollectionUtil.isNullOrEmpty(tag.getCategoryIdList())) {
                        return false;
                    } else {
                        return tag.getCategoryIdList().contains(String.valueOf(OrderTagConsts.TAG_CATEGORY_ID_EXCLUDE_PERFORMANCE));
                    }
                });
                log.debug("工单[{}] tag信息:{}", dto.getOrderId(), esOrderWork.getOrderTagList());

                dto.setExcludePerformance(isExcludePerformace);
            }

            // 会员相关
            if (Objects.equals(working.getMember(), GlobalConsts.YES)) {
                try (HintManager hintManager = HintManager.getInstance()) {
                    OrderMember orderMember = orderMemberService.findMemberByKey(working.getWorkId());
                    if (orderMember != null && Objects.equals(orderMember.getVerify(), GlobalConsts.YES) && Objects
                            .equals(orderMember.getReviewResult(), OrderConsts.ORDER_MEMBER_REVIEW_RESULT_DOING)
                            && Objects.equals(orderMember.getReviewStatus(),
                            OrderConsts.ORDER_MEMBER_REVIEW_STATUS_WAIT_MASTER)) {
                        dto.setReviewFlag(GlobalConsts.YES);
                    } else {
                        dto.setReviewFlag(GlobalConsts.NO);
                    }
                }
            }

            // 厂商单相关，如邮寄旧件标识，厂商审核标识
            if (Objects.equals(working.getSourceType(), OrderConsts.ORDER_SOURCE_TYPE_FACTORY)
                    && Objects.equals(working.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F)) {
                boolean waitFactoryReview = false;
                boolean waitPartPost = false;
                FcOrderPartCheckDTO fcPartCheck = orderFactoryPartService.doFactoryPartCheck(dto.getOrderId());
                if (fcPartCheck.isContainsFcPart()) {
                    waitFactoryReview = fcPartCheck.isContainsWaiting4FcReview();
                    waitPartPost = (fcPartCheck.isNeedReturnFcPart() || fcPartCheck.isContainsReturnFcPartWaiting4Post());
                }
                dto.setWaitFactoryReview(waitFactoryReview ? GlobalConsts.YES : GlobalConsts.NO);
                dto.setWaitPartsPost(waitPartPost ? GlobalConsts.YES : GlobalConsts.NO);
            }

            // 分润预估相关数据
            if (!Objects.equals(working.getPlatWork(), com.zmn.consts.GlobalConsts.PLAT_MARK_CNHB)) {
                try {
                    SharingEstimateVO sharingEstimate = orderWorkERPQueryBService.findSharingEstimate(dto.getOrderId(), dto.getWorkId(), false, true);
                    if (Objects.nonNull(sharingEstimate)) {
                        dto.setSharingEstimate(BeanMapper.map(sharingEstimate, WorkSharingEstimateDTO.class));
                    }
                } catch (OmsBaseException e) {
                    log.debug("工单[{}]无法获取分润信息:{}", dto.getWorkId(), e.getMessage());
                }
            }

            // 迟到赔显示到列表
            if (NumberUtil.isNotNullOrZero(dto.getDiscountActivityId())) {
                dto.setLateAmount(orderDiscountCalcBService.getLateAmount(dto.getOrderId(), dto.getDiscountActivityId()));
            }

            // 处理产品名称
            dto.setProductInfo(ProductInfoUtil.getProductName(dto.getProductInfo()));

            // 『VIP渠道』标识
            Integer vipChannel = vipChannelCache.get(dto.getChannelId());
            if (vipChannel == null) {
                vipChannel = this.getVipChannelFlag(dto.getChannelId());
                vipChannelCache.put(dto.getChannelId(), vipChannel);
            }
            dto.setVipChannel(vipChannel);

            ConfOrderChannelDRO confOrderChannelDRO = channelConfCache.get(dto.getChannelId());
            try {
                if (Objects.isNull(confOrderChannelDRO)) {
                    confOrderChannelDRO = confOrderChannelBService.getByChannelId(dto.getChannelId());
                    channelConfCache.put(dto.getChannelId(), confOrderChannelDRO);
                }
            } catch (OmsBaseException e) {
                e.printStackTrace();
            }
            if (Objects.nonNull(confOrderChannelDRO)) {
                // 渠道邀评
                dto.setNeedGuideInviteComment(confOrderChannelDRO.getInviteComment());
                // 工程师app控制
                boolean canCancel = StringUtil.isNotBlank(confOrderChannelDRO.getWorkOrderCancelType()) &&
                        StringUtil.convertStrsToList(confOrderChannelDRO.getWorkOrderCancelType())
                                .contains(ConfChannelWorkOrderTypeEnum.CONSTS_GCSAPP);
                if (!canCancel) {
                    dto.setCancelApplyUserType(GlobalConsts.NONE);
                }
            }

            // 优质订单判断
            // dto.setHighValueOrder(this.isHighQualityOrder(dto.getOrderId()) ? GlobalConsts.YES : GlobalConsts.NO);
            dto.setHighValueOrder(GlobalConsts.NO);

            // 高等级工程师
            dto.setHighLevelEngineer(GlobalConsts.NO);

            // 去掉高等级工程师的设置，谢文兵 2022.09.27
//            do {
//                if (CollectionUtil.isNullOrEmpty(compositeScoreList)) {
//                    break;
//                }
//
//                if (Objects.isNull(esOrderWork)) {
//                    break;
//                }
//
//                for (EngineerProductGroupCompositeScoreForDispatchOrderDRO scoreDRO : compositeScoreList) {
//                    if (Objects.equals(scoreDRO.getProductGroupId(), esOrderWork.getServProductGroupId())) {
//                        dto.setHighLevelEngineer(scoreDRO.getHighGradeFlag());
//                        break;
//                    }
//                }
//
//            } while(false);

            dtoList.add(dto);
        }

        try {
            // 处理标签
            this.processOrderTagList(dtoList);
        } catch (Exception e) {
            log.error("工单列表获取处理标签错误", e);
        }

        // 工单日程
        try {
            orderWorkProgrammeBService.processWorkDetailProgramList(dtoList);
        } catch (Exception e) {
            log.error("工单列表获取日程信息错误", e);
        }

        // 新单
        List<WorkListItemDTO> newWorkList = dtoList.stream()
                .filter(dto -> Objects.equals(dto.getStatus(), OrderStatusConsts.WORK_STATUS_DISTRIBUTE))
                .collect(Collectors.toList());

        // 进行中的
        List<WorkListItemDTO> doingWorkList = dtoList.stream().filter(dto -> {
            boolean isDistribute = Objects.equals(dto.getStatus(), OrderStatusConsts.WORK_STATUS_DISTRIBUTE);
            boolean isTake = Objects.equals(dto.getStatus(), OrderStatusConsts.WORK_STATUS_TAKE);
            boolean isVisit = Objects.equals(dto.getStatus(), OrderStatusConsts.WORK_STATUS_VISIT);
            boolean isReview = Objects.equals(dto.getStatus(), OrderStatusConsts.WORK_STATUS_SERVICE_COMPLETE);
            return isDistribute || isTake || isVisit || isReview;
        }).collect(Collectors.toList());

        Date dateStart = DateUtil.getDateStart(DateUtil.addDays(DateUtil.getNow(), 1));
        long timeStart = dateStart.getTime();

        // 无预约时间
        List<WorkListItemDTO> noDutyTimeCollect = doingWorkList.stream().filter(dto -> Objects.isNull(dto.getDutyTime())).collect(Collectors.toList());
        // 今天之前的订单，包含今天
        List<WorkListItemDTO> beforeTodayCollect = doingWorkList.stream().filter(dto -> Objects.nonNull(dto.getDutyTime()) && dto.getDutyTime().getTime() < timeStart).collect(Collectors.toList());
        // 今天之后的订单
        List<WorkListItemDTO> afterTodayCollect = doingWorkList.stream().filter(dto -> Objects.nonNull(dto.getDutyTime()) && dto.getDutyTime().getTime() >= timeStart).collect(Collectors.toList());

        List<WorkListItemDTO> leaveCollect = Lists.newArrayListWithExpectedSize(beforeTodayCollect.size()
                + noDutyTimeCollect.size()
                + afterTodayCollect.size());

        leaveCollect.addAll(beforeTodayCollect);
        leaveCollect.addAll(noDutyTimeCollect);
        leaveCollect.addAll(afterTodayCollect);

        // 处理预估收入字段
        if (CollectionUtil.isNotNullOrEmpty(newWorkList)) {
            WorkListItemDTO workListItemDTO = newWorkList.get(0);
            OrderWork orderWork = orderWorkService.findOrderWorkByKey(workListItemDTO.getOrderId(), workListItemDTO.getWorkId());
            workListItemDTO.setForecastTotalAmount(this.getForecastTotalAmount(orderWork));
        }


        workListDTO.setNewWorkOrders(newWorkList);
        workListDTO.setDoingWorkOrders(leaveCollect);

        return workListDTO;
    }




    private Integer getForecastTotalAmount(OrderWork orderWork) {
        if (Objects.isNull(orderWork)) {
            return null;
        }

        // 上门后不显示
        if (orderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_VISIT) {
            return null;
        }

        if (!Objects.equals(orderWork.getServCategId(), GlobalConsts.SERV_CATEG_CLEAN)) {
            return null;
        }

        if (NumberUtil.isNullOrZero(orderWork.getServProductGroupId())) {
            return null;
        }

        if (NumberUtil.isNullOrZero(orderWork.getManageCompanyId())) {
            return null;
        }

        List<OrderServiceItem> orderServiceItems = orderServiceItemService.listByOrderId(orderWork.getOrderId());

        if (CollectionUtil.isNullOrEmpty(orderServiceItems)) {
            return null;
        }

        ClearingOrderAccountDIO dio = new ClearingOrderAccountDIO();
        dio.setWorkId(orderWork.getWorkId());
        dio.setPlat(orderWork.getPlatWork());
        dio.setBizType(orderWork.getBizType());
        dio.setSpCompanyId(orderWork.getManageCompanyId());
        dio.setProductGroupId(orderWork.getServProductGroupId());
        int internalSettlementPrice = orderServiceItems.stream()
                .filter(e -> e.getInternalTotalPrice() != null)
                .mapToInt(OrderServiceItem::getInternalTotalPrice).sum();
        dio.setInternalStatementAmount(internalSettlementPrice);
        dio.setEngineerId(orderWork.getMasterId());

        try {
            log.info("{} engineerAccountRemoteService.clearingOrderAccount dio={}", orderWork.getWorkId(), dio);
            ResponseDTO<ClearingOrderAccountDRO> responseDTO = engineerAccountRemoteService.clearingOrderAccount(dio);
            log.info("{} engineerAccountRemoteService.clearingOrderAccount responseDTO={}", orderWork.getWorkId(), responseDTO);
            if (!responseDTO.isSuccess() || Objects.isNull(responseDTO.getData())) {
                return null;
            }
            ClearingOrderAccountDRO data = responseDTO.getData();
            return data.getReserveAmount();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("{} engineerAccountRemoteService.clearingOrderAccount error={}", orderWork.getWorkId(), e.getMessage());
        }
        return null;
    }

    /**
     * 处理用户标签
     *
     * @param workList
     */
    private void processOrderTagList(List<WorkListItemDTO> workList) {

        List<Long> workIdList = workList.stream().map(WorkListItemDTO::getWorkId).collect(Collectors.toList());
        if (CollectionUtil.isNullOrEmpty(workIdList)) {
            return;
        }
        // 查询订单标签
        List<OrderTag> orderTagList = orderTagService.listOrderTagByOrderIdList(workIdList);

        Map<Long, List<OrderTag>> orderTagMap = null;
        if (CollectionUtil.isNotNullOrEmpty(orderTagList)) {
            // 标签处理
            orderTagMap = orderTagList.stream().collect(Collectors.groupingBy(OrderTag::getWorkId));
        }

        for (WorkListItemDTO dto : workList) {
            if (CollectionUtil.isNotNullOrEmpty(orderTagMap)) {
                // 标签
                List<OrderTag> tagList = orderTagMap.get(dto.getWorkId());

                // 过滤优质订单及高价值用户
                List<OrderTag> tagListFilter = null;
                if (CollectionUtil.isNotNullOrEmpty(tagList)) {
                    tagListFilter = tagList.stream().filter(tag -> {
                        boolean needFilter = Objects.equals(tag.getTagId(), OrderTagConsts.USER_TAG_ID_HIGH_VALUE) ||
                                Objects.equals(tag.getTagId(), OrderTagConsts.TAG_ID_HIGH_VALUE_USER) ||
                                Objects.equals(tag.getTagId(), OrderTagConsts.TAG_ID_HIGH_QUALITY);
                        return !needFilter;
                    }).collect(Collectors.toList());
                }

                if (CollectionUtil.isNotNullOrEmpty(tagListFilter)) {
                    dto.setTagList(BeanMapper.mapList(tagListFilter, WorkTagDTO.class));
                    // 高价值用户标签处理
                    boolean anyMatch = tagListFilter.stream().anyMatch(tag ->
                            Objects.equals(tag.getTagId(), OrderTagConsts.USER_TAG_ID_HIGH_VALUE) || Objects.equals(tag.getTagId(), OrderTagConsts.TAG_ID_HIGH_VALUE_USER)
                    );
                    dto.setHighValueUser(anyMatch ? GlobalConsts.YES : GlobalConsts.NO);
                }
            }

            if (CollectionUtil.isNullOrEmpty(dto.getTagList())) {
                dto.setTagList(Lists.newArrayList());
            }
            if (Objects.equals(dto.getNeedGuideInviteComment(), GlobalConsts.YES)) {
                WorkTagDTO workTagDTO = new WorkTagDTO();
                workTagDTO.setTagId(OrderTagConsts.TAG_ID_CHANNEL_INVITE);
                workTagDTO.setTagName(OrderTagConsts.getTagName(OrderTagConsts.TAG_ID_CHANNEL_INVITE));
                dto.getTagList().add(workTagDTO);
            }

            if (dto.getServItemType() == OrderConsts.SERVICE_ITEM_TYPE_ADVANCE_PAY) {
                WorkTagDTO workTagDTO = new WorkTagDTO();
                workTagDTO.setTagId(OrderTagConsts.TAG_ID_WORK_ADVANCE_PAY);
                workTagDTO.setTagName(OrderTagConsts.getTagName(OrderTagConsts.TAG_ID_WORK_ADVANCE_PAY));
                dto.getTagList().add(workTagDTO);
            } else if (servItemBService.isQuotationThreeType(dto.getServItemType(), dto.getFinalPrice())) {
                WorkTagDTO workTagDTO = new WorkTagDTO();
                workTagDTO.setTagId(OrderTagConsts.TAG_ID_WORK_QUOTATION_THREE);
                workTagDTO.setTagName(OrderTagConsts.getTagName(OrderTagConsts.TAG_ID_WORK_QUOTATION_THREE));
                dto.getTagList().add(workTagDTO);
            }
        }
    }

    /**
     * 描述:将LIST进行分割生成版本号
     *
     * @date 2018/12/7 15:26
     */
    private String getVersion(WorkListDTO workListDTO) {
        List<WorkListItemDTO> newList = workListDTO.getNewWorkOrders();
        List<WorkListItemDTO> doingList = workListDTO.getDoingWorkOrders();

        // 没有数据时存空串
        if (newList.isEmpty() && doingList.isEmpty()) {
            return "";
        }

        String newStr = appendStr(newList);
        String doingStr = appendStr(doingList);
        String totalStr = newStr + ";" + doingStr;
        return EncodeUtil.getMD5For32UTF8(totalStr);
    }

    /**
     * 描述:字符串拼接
     *
     * @param list 列表
     * @return String
     * @author zhoulin
     * @date 2018/12/7 15:27
     */
    private String appendStr(List<WorkListItemDTO> list) {
        if (!list.isEmpty()) {
            StringBuilder sb = new StringBuilder();

            list.forEach(item -> {
                sb.append(item.getWorkId());
                sb.append("_");
                sb.append(item.getStatus());
                sb.append(",");
            });

            return sb.toString();
        }

        return "";
    }

    /**
     * 完成工单列表
     *
     * @param masterId
     */
    @Override
    public WorkListDTO getCompleteWorkListFromEs(Integer plat, Integer masterId, Date startDate,
                                                 Date endDate, Integer startIndex, Integer pageSize) {

        String startTimeStr = DateUtil.toString(startDate, DateUtil.FORMAT_DEFAULT);
        String endTimeStr = DateUtil.toString(endDate, DateUtil.FORMAT_DEFAULT);
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.filter(QueryBuilders.termQuery("masterList.masterId", masterId));
        QueryBuilder masterQuery = QueryBuilders.nestedQuery("masterList", queryBuilder, ScoreMode.None);
        // 若工程师为学徒身份 只显示其主工程师工单 过滤其从工程师身份的工单
        log.debug("getCompleteWorkListFromEs#checkIsStudent 入参 [{}]",masterId);
        ResponseDTO<Boolean> studentResponseDTO = engineerListRemoteService.checkIsStudent(masterId);
        log.debug("getCompleteWorkListFromEs#checkIsStudent 出参 [{}]",JSON.toJSONString(studentResponseDTO));
        if (studentResponseDTO.isSuccess() && studentResponseDTO.getData()) {
            masterQuery = QueryBuilders.termQuery("masterId", masterId);
        }
        NativeSearchQuery build = new NativeSearchQueryBuilder()
                .withPageable(PageRequest.of(startIndex / pageSize, pageSize))
                .withSort(SortBuilders.fieldSort("completeTime").order(SortOrder.DESC))
                .withQuery(boolQuery()
                        .filter(masterQuery)
                        .filter(QueryBuilders.termsQuery("status",
                                Lists.newArrayList(OrderStatusConsts.WORK_STATUS_TAKE, OrderStatusConsts.WORK_STATUS_VISIT
                                        , OrderStatusConsts.WORK_STATUS_COMPLETE, OrderStatusConsts.WORK_STATUS_CHECKOUT,
                                        OrderStatusConsts.WORK_STATUS_ACCOUNT)))
                        .filter(boolQuery()
                                .should(QueryBuilders.rangeQuery("cancelTime").from(startTimeStr).to(endTimeStr))
                                .should(QueryBuilders.rangeQuery("completeTime").from(startTimeStr).to(endTimeStr))
                        ))
                .build();

        List<EsOrderWork> orderWorkList = orderWorkEsBService.listPageByQuery(build);
        // yeyx过滤未完成工单
        if (plat == GlobalConsts.PLAT_MARK_YEYX) {
            orderWorkList = orderWorkList.stream().filter(e -> Objects.nonNull(e.getCompleteTime())).collect(Collectors.toList());
        }
        List<WorkListItemDTO> dtoList = Lists.newArrayList();
        orderWorkList.forEach(work -> {
            WorkListItemDTO dto = new WorkListItemDTO();
            dto.setWorkId(work.getId());
            dto.setOrderId(work.getOrderId());
            dto.setType(work.getType());
            dto.setStatus(work.getStatus());
            dto.setResultStatus(work.getResultStatus());
            dto.setProductInfo(work.getProductInfo());
            dto.setTotalAmount(work.getTotalAmount());
            dto.setCompleteTime(work.getCompleteTime());
            dto.setBizType(work.getBizType());
            dto.setMainService(masterId.equals(work.getMasterId()) ? GlobalConsts.YES : GlobalConsts.NO);
            dto.setAccountTime(work.getAccountTime());
            Integer resultStatus = work.getResultStatus();
            if (Objects.equals(resultStatus, OrderStatusConsts.WORK_RESULT_FAIL)) {
                dto.setFailTime(work.getResultTime());
            }
            // 分润预估相关数据
            SharingEstimateVO sharingEstimate = null;
            try {
                sharingEstimate = orderWorkERPQueryBService.findSharingEstimate(dto.getOrderId(), dto.getWorkId(), false, true);
                if (Objects.nonNull(sharingEstimate)) {
                    dto.setSharingEstimate(BeanMapper.map(sharingEstimate, WorkSharingEstimateDTO.class));
                }
            } catch (OmsBaseException e) {
                log.debug("工单[{}]无法获取分润信息:{}", dto.getWorkId(), e.getMessage());
            }

            // 处理产品名称
            dto.setProductInfo(ProductInfoUtil.getProductName(dto.getProductInfo()));

            dtoList.add(dto);
        });
        log.info("历史工单列表 dro masterId :{}, size:{}", masterId, dtoList.size());
        WorkListDTO workListDTO = new WorkListDTO();
        workListDTO.setCompleteWorkOrders(dtoList);
        return workListDTO;

    }


    /**
     * 完成工单列表
     *
     * @param masterId
     */
    @Override
    public List<WorkListItemDTO> listCompleteWorkFromEs(Integer plat, Integer masterId, Integer tapType, Date startDate,
                                                        Date endDate, Integer startIndex, Integer pageSize) {
        tapType = Optional.ofNullable(tapType).orElse(MasterWorkConsts.QUERY_TAB_COMPLETE);

        // 状态过滤
        SortOrder completeTimeSort = SortOrder.DESC;
        TermsQueryBuilder filterStatusBuilder;
        TermQueryBuilder filterResultStatusBuilder = null;
        TermQueryBuilder filterPartRetainBuilder = null;
        switch (tapType) {
            case MasterWorkConsts.QUERY_TAB_COMPLETE:
                filterStatusBuilder = QueryBuilders.termsQuery("status", Arrays.asList(OrderStatusConsts.WORK_STATUS_COMPLETE));
                break;
            case MasterWorkConsts.QUERY_TAB_CHECKOUT:
                filterStatusBuilder = QueryBuilders.termsQuery("status", Arrays.asList(OrderStatusConsts.WORK_STATUS_CHECKOUT));
                break;
            case MasterWorkConsts.QUERY_TAB_ACCOUNT:
                filterStatusBuilder = QueryBuilders.termsQuery("status", Arrays.asList(OrderStatusConsts.WORK_STATUS_ACCOUNT));
                break;
            case MasterWorkConsts.QUERY_TAB_FAIL:
                filterStatusBuilder = QueryBuilders.termsQuery("status", Arrays.asList(OrderStatusConsts.WORK_STATUS_TAKE, OrderStatusConsts.WORK_STATUS_VISIT,
                        OrderStatusConsts.WORK_STATUS_COMPLETE, OrderStatusConsts.WORK_STATUS_CHECKOUT, OrderStatusConsts.WORK_STATUS_ACCOUNT));
                filterResultStatusBuilder = QueryBuilders.termQuery("resultStatus", OrderStatusConsts.WORK_RESULT_FAIL);
                break;
            case MasterWorkConsts.QUERY_TAB_PART_RETAIN:
                filterStatusBuilder = QueryBuilders.termsQuery("status",
                        Arrays.asList(OrderStatusConsts.WORK_STATUS_COMPLETE, OrderStatusConsts.WORK_STATUS_CHECKOUT, OrderStatusConsts.WORK_STATUS_ACCOUNT));
                filterPartRetainBuilder = QueryBuilders.termQuery("partRetain", GlobalConsts.YES);
                completeTimeSort = SortOrder.ASC;
                break;
            case MasterWorkConsts.QUERY_TAB_PART_SUBMIT:
                filterStatusBuilder = QueryBuilders.termsQuery("status",
                        Arrays.asList(OrderStatusConsts.WORK_STATUS_COMPLETE, OrderStatusConsts.WORK_STATUS_VISIT, OrderStatusConsts.WORK_STATUS_SERVICE_COMPLETE));
                filterPartRetainBuilder = QueryBuilders.termQuery("orderPartAddition.reviewStatus", GlobalConsts.LEVEL_4);
                completeTimeSort = SortOrder.ASC;
                break;
            default:
                filterStatusBuilder = QueryBuilders.termsQuery("status", Arrays.asList(OrderStatusConsts.WORK_STATUS_TAKE, OrderStatusConsts.WORK_STATUS_VISIT,
                        OrderStatusConsts.WORK_STATUS_COMPLETE, OrderStatusConsts.WORK_STATUS_CHECKOUT, OrderStatusConsts.WORK_STATUS_ACCOUNT));
                break;
        }

        // 工程师过滤
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.filter(QueryBuilders.termQuery("masterList.masterId", masterId));
        QueryBuilder masterQuery = QueryBuilders.nestedQuery("masterList", queryBuilder, ScoreMode.None);
        // todo fubiao
        log.info("listCompleteWorkFromEs#checkIsStudent 入参 [{}]",masterId);
        ResponseDTO<Boolean> studentResponseDTO = engineerListRemoteService.checkIsStudent(masterId); // 若工程师为学徒身份 只显示其主工程师工单 过滤其从工程师身份的工单
        log.info("listCompleteWorkFromEs#checkIsStudent 出参 [{}]",JSON.toJSONString(studentResponseDTO));
        if (studentResponseDTO.isSuccess() && studentResponseDTO.getData()) {
            masterQuery = QueryBuilders.termQuery("masterId", masterId);
        }
        // 时间过滤
        String startTimeStr = DateUtil.toString(startDate, DateUtil.FORMAT_DEFAULT);
        String endTimeStr = DateUtil.toString(endDate, DateUtil.FORMAT_DEFAULT);
        BoolQueryBuilder dateFilter = boolQuery()
                .should(QueryBuilders.rangeQuery("cancelTime").from(startTimeStr).to(endTimeStr))
                .should(QueryBuilders.rangeQuery("completeTime").from(startTimeStr).to(endTimeStr));

        BoolQueryBuilder boolQueryBuilder = boolQuery()
                .filter(filterStatusBuilder)
                .filter(masterQuery)
                .filter(dateFilter);
        // 只查新单和返修单
        boolQueryBuilder.filter(QueryBuilders.termsQuery("type", Arrays.asList(OrderConsts.ORDER_TYPE_NEW, OrderConsts.ORDER_TYPE_REWORK)));

        // 配件保留过滤
        if (Objects.nonNull(filterPartRetainBuilder)) {
            boolQueryBuilder.filter(filterPartRetainBuilder);
        }
        // 失败过滤
        if (Objects.nonNull(filterResultStatusBuilder)) {
            boolQueryBuilder.filter(filterResultStatusBuilder);
        }
        NativeSearchQuery build = new NativeSearchQueryBuilder()
                .withPageable(PageRequest.of(startIndex / pageSize, pageSize))
                .withSort(SortBuilders.fieldSort("completeTime").order(completeTimeSort))
                .withQuery(boolQueryBuilder)
                .build();

        log.debug("历史订单查询==>{}", boolQueryBuilder.toString());
        List<EsOrderWork> orderWorkList = orderWorkEsBService.listPageByQuery(build);
        // yeyx过滤未完成工单
        if (plat == GlobalConsts.PLAT_MARK_YEYX) {
            orderWorkList = orderWorkList.stream().filter(e -> Objects.nonNull(e.getCompleteTime())).collect(Collectors.toList());
        }
        List<WorkListItemDTO> dtoList = Lists.newArrayList();
        Integer finalTapType = tapType;
        orderWorkList.forEach(work -> {
            WorkListItemDTO dto = new WorkListItemDTO();
            dto.setWorkId(work.getId());
            dto.setOrderId(work.getOrderId());
            dto.setType(work.getType());
            dto.setStatus(work.getStatus());
            dto.setResultStatus(work.getResultStatus());
            dto.setProductInfo(work.getProductInfo());
            dto.setTotalAmount(work.getTotalAmount());
            dto.setCompleteTime(work.getCompleteTime());
            dto.setBizType(work.getBizType());
            dto.setMainService(masterId.equals(work.getMasterId()) ? GlobalConsts.YES : GlobalConsts.NO);
            dto.setAccountTime(work.getAccountTime());
            Integer resultStatus = work.getResultStatus();
            if (Objects.equals(resultStatus, OrderStatusConsts.WORK_RESULT_FAIL)) {
                dto.setFailTime(work.getResultTime());
            }
            // 分润预估相关数据
            SharingEstimateVO sharingEstimate = null;
            try {
                sharingEstimate = orderWorkERPQueryBService.findSharingEstimate(dto.getOrderId(), dto.getWorkId(), false, true);
                if (Objects.nonNull(sharingEstimate)) {
                    dto.setSharingEstimate(BeanMapper.map(sharingEstimate, WorkSharingEstimateDTO.class));
                }
            } catch (OmsBaseException e) {
                log.debug("工单[{}]无法获取分润信息:{}", dto.getWorkId(), e.getMessage());
            }
            // 处理产品名称
            dto.setProductInfo(ProductInfoUtil.getProductName(dto.getProductInfo()));
            if (Objects.equals(MasterWorkConsts.QUERY_TAB_PART_RETAIN, finalTapType)) {
                // 截至报销时间=完成时间+24小时
                dto.setEndPartRetailTime(DateUtil.getDateTimeStr(DateUtil.addDays(work.getCompleteTime(), 1)));
            }
            dtoList.add(dto);
        });

        log.info("历史工单列表 dro masterId :{}, size:{}", masterId, dtoList.size());
        return dtoList;
    }

    /**
     * 工单详情
     *
     * @param orderId
     * @param workId
     * @param masterId
     */
    @Override
    public WorkDetailDTO getWorkDetail(Integer plat, Long orderId, Long workId, Integer masterId, Integer agent)
            throws OmsBaseException {
        WorkDetailDTO workDetailDTO = new WorkDetailDTO();


        /*基本信息*/

        OrderWork orderWork = orderWorkService.findMasterWorkDetail(orderId, workId, masterId);


        if (orderWork == null) {
            throw new OmsBaseException("工单已被处理");
        }
        boolean isCancel = Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DISCARD) ||
                (Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_FAIL) && Objects.isNull(orderWork.getCompleteTime()));
        if (isCancel) {
            throw new OmsBaseException("订单已取消");
        }

        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderId);
        OrderExtend orderExtend = orderExtendService.findOrderExtendByOrderId(orderId);
        MasterWorking masterWorking = masterWorkingService.findMasterWorkingByWorkId(orderId);
        // 是否啄木鸟自营
        boolean zmnDirectly = Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_ZMN) && Objects
                .equals(agent, 1);

        /////////////////////////////////////////////////////////////////////////////////////////////////
        workDetailDTO.setOrderId(orderId);
        workDetailDTO.setWorkId(workId);
        workDetailDTO.setMasterId(orderWork.getMasterId());
        workDetailDTO.setPlatWork(orderWork.getPlatWork());
        workDetailDTO.setCompanyId(orderWork.getCompanyId());
        workDetailDTO.setManageCompanyId(orderWork.getManageCompanyId());
        workDetailDTO.setType(orderWork.getType());
        workDetailDTO.setGrabType(orderWork.getGrabType());
        workDetailDTO.setStatus(orderWork.getStatus());
        workDetailDTO.setIsLeave(orderWork.getIsLeave());
        workDetailDTO.setResultStatus(orderWork.getResultStatus());
        workDetailDTO.setDutyTime(orderWork.getDutyTime());
        workDetailDTO.setServCategId(orderDetail.getServCategId());
        workDetailDTO.setServCategName(orderDetail.getServCategName());
        workDetailDTO.setCategOneId(orderDetail.getCategOneId());
        workDetailDTO.setCategId(orderDetail.getCategId());
        workDetailDTO.setShowCategOneId(orderWork.getShowCategOneId());
        workDetailDTO.setShowCategId(orderWork.getShowCategId());
        workDetailDTO.setProductId(orderDetail.getProductId());
        workDetailDTO.setShowProductId(orderWork.getShowProductId());
        workDetailDTO.setProductInfo(ProductInfoUtil.getProductName(orderDetail.getProductInfo()));
        workDetailDTO.setFault(orderDetail.getFault());
        workDetailDTO.setRemark(orderDetail.getRemark());
        workDetailDTO.setUserName(orderDetail.getUserName());
        workDetailDTO.setContactName(orderDetail.getContactName());
        workDetailDTO.setTelephone(orderDetail.getTelephone());
        workDetailDTO.setTelephone2(orderDetail.getTelephone2());
        workDetailDTO.setTelephone3(orderDetail.getTelephone3());
        workDetailDTO.setProvinceId(orderDetail.getProvinceId());
        workDetailDTO.setProvinceName(orderDetail.getProvinceName());
        workDetailDTO.setCityId(orderWork.getCityId());
        workDetailDTO.setCityName(orderDetail.getCityName());
        workDetailDTO.setCountyId(orderDetail.getCountyId());
        workDetailDTO.setCountyName(orderDetail.getCountyName());
        workDetailDTO.setStreet(orderDetail.getStreet());
        workDetailDTO.setAddress(orderDetail.getAddress());
        workDetailDTO.setLongitude(orderDetail.getLongitude());
        workDetailDTO.setLatitude(orderDetail.getLatitude());
        workDetailDTO.setBizType(orderWork.getBizType());
        workDetailDTO.setBizLine(orderWork.getBizLine());
        workDetailDTO.setManualCode(orderWork.getManualCode());
        workDetailDTO.setSourceType(orderWork.getSourceType());
        workDetailDTO.setMember(orderWork.getMember());
        workDetailDTO.setStandardPrice(orderWork.getStandardPrice());
        workDetailDTO.setFinalPrice(orderWork.getFinalPrice());
        workDetailDTO.setDelivery(orderWork.getDelivery());
        workDetailDTO.setWaitPart(orderWork.getWaitPart());
        workDetailDTO.setPartUse(orderWork.getPartUse());
        workDetailDTO.setOuterId(orderWork.getOuterId());
        workDetailDTO.setServItemType(orderWork.getServItemType());
        workDetailDTO.setVisitUserId(orderWork.getVisitUserId());
        workDetailDTO.setUserId(orderWork.getUserId());
        workDetailDTO.setServiceCompleteReviewStatus(orderWork.getServiceCompleteReviewStatus());
        workDetailDTO.setBizModeSource(orderWork.getBizModeSource());
        workDetailDTO.setDiscountActivityId(orderWork.getDiscountActivityId());
        workDetailDTO.setLateAmount(orderDiscountCalcBService.getLateAmount(orderWork.getOrderId(), orderWork.getDiscountActivityId()));
        workDetailDTO.setServProductGroupId(orderWork.getServProductGroupId());
        workDetailDTO.setPartRetain(orderWork.getPartRetain());
        workDetailDTO.setContactTime(orderWork.getContactTime());
        workDetailDTO.setDistributeTime(orderWork.getDistributeTime());
        workDetailDTO.setPayDiscountAmount(orderWork.getPayDiscountAmount());

        // 审核失败原因
        if (Objects.equals(orderWork.getServiceCompleteReviewStatus(), OrderConsts.REVIEW_STATUS_FAIL)) {
            List<OrderRemarkDetail> orderRemarkDetails = orderRemarkDetailService.listOrderRemarkDetailByOrderIdList(Arrays.asList(orderId));
            if (CollectionUtil.isNotNullOrEmpty(orderRemarkDetails)) {
                orderRemarkDetails = orderRemarkDetails.stream().filter(e -> Objects.equals(e.getType(), OrderConsts.ORDER_REMARK_TYPE_REVIEW_FAIL)).collect(Collectors.toList());
                StringBuilder sb = new StringBuilder();
                if (orderRemarkDetails.size() > 0) {
                    orderRemarkDetails.forEach(x -> sb.append(x.getMapName()).append("，"));
                }
                OrderRemark orderRemark = orderRemarkService.findByOrderIdAndType(orderId, workId, OrderConsts.ORDER_REMARK_TYPE_REVIEW_FAIL);
                if (Objects.nonNull(orderRemark)) {
                    sb.append(orderRemark.getContent());
                }
                workDetailDTO.setServiceCompleteReviewReason(sb.toString());
            }
        }

        // 小号绑定处理
        processXNOBindStatus(orderDetail, orderWork, workDetailDTO);

        // 工单本身为固定价格或者服务类型为清洗，不能改价格
        if (orderWork.getFixPrice() == GlobalConsts.YES
                || orderDetail.getServCategId() == GlobalConsts.SERV_CATEG_CLEAN) {
            workDetailDTO.setFixPrice(GlobalConsts.YES);
        } else {
            workDetailDTO.setFixPrice(GlobalConsts.NO);
        }

        // 金额
        workDetailDTO.setOriginalAmount(orderWork.getOriginalAmount());
        workDetailDTO.setTotalAmount(orderWork.getTotalAmount());
        workDetailDTO.setMasterAmount(orderWork.getMasterAmount());
        // 合并多个预付款到PrepayAmount
        //        workDetailDTO.setPrepayAmount(orderWork.getPrepayAmount());
        //        workDetailDTO.setChannelPrepayAmount(orderWork.getChannelPrepayAmount());
        Integer prepayAmount = orderWork.getPrepayAmount();
        Integer channelPrepayAmount = orderWork.getChannelPrepayAmount();
        if (prepayAmount != null || channelPrepayAmount != null) { // 只有其中一个有值才处理
            if (prepayAmount == null) {
                prepayAmount = 0;
            }
            if (channelPrepayAmount == null) {
                channelPrepayAmount = 0;
            }
            workDetailDTO.setPrepayAmount(prepayAmount + channelPrepayAmount);
        }
        workDetailDTO.setDepositAmount(orderWork.getDepositAmount());
        workDetailDTO.setDepositStatus(orderWork.getDepositStatus());
        workDetailDTO.setDiscountAmount(orderWork.getDiscountAmount());
        workDetailDTO.setOnlyVisit(orderWork.getOnlyVisit());

        // 渠道名称
        workDetailDTO.setChannelId(orderWork.getChannelId());

        ResponseDTO<ChannelDRO> channelRespDTO = channelListRemoteService.getByChannelId(orderWork.getChannelId());
        if (channelRespDTO.isSuccess() && channelRespDTO.getData() != null) {
            // 渠道别名、『VIP渠道』标识
            workDetailDTO.setChannelName(channelRespDTO.getData().getAnotherName());
            workDetailDTO.setVipChannel(Optional.ofNullable(channelRespDTO.getData().getLevel()).orElse(0) == ChannelLevelEnum.VIP.getCode() ? GlobalConsts.YES : GlobalConsts.NO);
        }

        ConfOrderChannelDRO confOrderChannelDRO = confOrderChannelBService.getByChannelId(orderWork.getChannelId());
        if (Objects.nonNull(confOrderChannelDRO)) {
            // 渠道说明
            workDetailDTO.setChannelDesc(confOrderChannelDRO.getDesc());
            // 渠道是否需要贴花标志，1：否，2：是
            workDetailDTO.setNeedApplique(confOrderChannelDRO.getApplique());
            // 渠道邀评
            this.processInviteComment(workDetailDTO, confOrderChannelDRO);
        }

        // 查询当前工程师是否允许转派，默认工程师不允许派单
        workDetailDTO.setEnableDistribute(GlobalConsts.NO);

        log.debug("getWorkDetail#getTakeConfig 入参 [{}]",masterId);
        ResponseDTO<EngineerTakeConfigDRO> responseDTO = engineerTakeConfigListRemoteService.getTakeConfig(masterId);
        log.debug("getWorkDetail#getTakeConfig 出参 [{}]",JSON.toJSONString(responseDTO));
        if (responseDTO.getData() != null && Objects.equals(responseDTO.getData().getTransPermitStatus(), GlobalConsts.YES)) {
            workDetailDTO.setEnableDistribute(GlobalConsts.YES);
        }

        // 派单电话
        switch (plat) {
            case GlobalConsts.PLAT_MARK_ZMN: {
                //                if (orderWork.getDistributerId() != null) {
                //                    ResponseDTO<StaffDRO> staffRespDTO = staffRemoteService.getStaffById(orderWork
                //                    .getDistributerId().intValue());
                //                    if (staffRespDTO.getStatusBool()) {
                //                        String distributorTel = staffRespDTO.getData().getPhone();
                //                        if (StringUtil.isBlank(distributorTel)) {
                //                            distributorTel = staffRespDTO.getData().getMobile();
                //                        }
                //
                //                        workDetailDTO.setDistributorTel(distributorTel);
                //                    }
                //                }

                // 啄木鸟平台派单电话固定为10101016
                workDetailDTO.setDistributorTel("10101016");
                break;
            }
            case GlobalConsts.PLAT_MARK_YEYX: {
                // 言而有信平台派单电话固定为4000665315
                workDetailDTO.setDistributorTel("4000665315");
                break;
            }
            case GlobalConsts.PLAT_MARK_SAAS: {
                // SAAS平台派单电话取商户电话
                ResponseDTO<CompanyContactDRO> companyContactDRO = companyListRemoteService.getCompanyContactDROById(orderWork.getManageCompanyId());
                if (companyContactDRO.isSuccess() && companyContactDRO.getData() != null) {
                    workDetailDTO.setDistributorTel(companyContactDRO.getData().getMobile());
                }

                break;
            }
            case GlobalConsts.PLAT_MARK_CNHB: {
                // 川南环保平台派单电话固定为10101016
                workDetailDTO.setDistributorTel("10101016");
                break;
            }
            default:
                break;
        }

        // 主管电话
        if (masterId != null && masterId != 0) {
            // todo fubiao
            log.info("getWorkDetail#getSupervisorByIdAndProductGroupId 入参 [{}] [{}]",masterId,orderWork.getServProductGroupId());
            ResponseDTO<SupervisorBasicDRO> remoteRespDTO = engineerSupervisorListRemoteService.getSupervisorByIdAndProductGroupId(masterId, orderWork.getServProductGroupId());
            log.info("getWorkDetail#getSupervisorByIdAndProductGroupId 出参 [{}]",JSON.toJSONString(remoteRespDTO));
            //logger.info("getSupervisorByEngineerIdAndBizType：remoteRespDTO={}", remoteRespDTO);
            if (remoteRespDTO.isSuccess() && remoteRespDTO.getData() != null) {
                SupervisorBasicDRO supervisorBasicDRO = remoteRespDTO.getData();

                MasterManagerDTO masterManagerDTO = new MasterManagerDTO();
                masterManagerDTO.setName(supervisorBasicDRO.getSupervisorName());
                masterManagerDTO.setMobile(supervisorBasicDRO.getMobile());

                List<MasterManagerDTO> managers = Lists.newArrayList(masterManagerDTO);
                workDetailDTO.setManagers(managers);
            }
        }

        // 全家享会员客服电话
        workDetailDTO.setMemberServiceNumber(baseCodeService.getMemberServicePhone(plat));

        // 全家享会员单可以操作的距离,单位米
        workDetailDTO.setMemberOrderOperationDistance(baseCodeService.getMemberOrderOperationDistance(plat));
        workDetailDTO.setSupportSaleMember(GlobalConsts.YES);

        OrderMember orderMember = orderMemberService.findMemberByKey(orderId);
        if (orderMember != null) {
            workDetailDTO.setReviewFlag(orderMember.getVerify()); // 会员单审核标志
            workDetailDTO.setVasReviewStatus(orderMember.getReviewStatus());// 审核状态
        }

        // 厂商单(厂商工单&保内)相关，如厂商说明、邮寄旧件标识
        if (Objects.equals(orderWork.getSourceType(), OrderConsts.ORDER_SOURCE_TYPE_FACTORY)) {
            // 厂商说明
            /*OrderFactory orderFactory = orderFactoryService.findOrderFactoryByKey(orderId);
            if (orderFactory != null) {
                ResponseDTO<FactoryDRO> factoryRespDTO = factoryListRemoteService.getFactoryById(orderFactory.getFactoryId());
                if (factoryRespDTO.isSuccess()) {
                    workDetailDTO.setFactoryId(factoryRespDTO.getData().getFactoryId());
                    workDetailDTO.setFactoryDesc(factoryRespDTO.getData().getServiceDescription());
                    workDetailDTO.setTechPhone(factoryRespDTO.getData().getTechPhone());
                }
            }*/

            if (Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F)) { // 保内
                boolean waitFactoryReview = false;
                boolean waitPartPost = false;
                FcOrderPartCheckDTO fcPartCheck = orderFactoryPartService
                        .doFactoryPartCheck(workDetailDTO.getOrderId());
                if (fcPartCheck.isContainsFcPart()) {
                    waitFactoryReview = fcPartCheck.isContainsWaiting4FcReview();
                    waitPartPost = (fcPartCheck.isNeedReturnFcPart() && fcPartCheck
                            .isContainsReturnFcPartWaiting4Post());
                }
                workDetailDTO.setWaitFactoryReview(waitFactoryReview ? GlobalConsts.YES : GlobalConsts.NO);
                workDetailDTO.setWaitPartsPost(waitPartPost ? GlobalConsts.YES : GlobalConsts.NO);

                workDetailDTO.setReviewSuccessParts(fcPartCheck.getReviewSuccessParts());
            }
        }

        /*图片*/
        if (orderExtend != null) {
            // 查询订单贴花照片列表
            String appliqueSrc = orderExtend.getAppliqueSrc();
            if (StringUtil.isNotBlank(appliqueSrc)) {
                String[] split = appliqueSrc.split(",");
                workDetailDTO.setAppliqueSrcList(Lists.newArrayList(split));
            }

            // 订单工程师拍照列表
            String imageSrc = orderExtend.getImageSrc();
            if (StringUtil.isNotBlank(imageSrc)) {
                String[] split = imageSrc.split(",");
                workDetailDTO.setImageSrcList(Lists.newArrayList(split));
            }

            // 订单工程师工作照列表
            String masterSrc = orderExtend.getMasterSrc();
            if (StringUtil.isNotBlank(masterSrc)) {
                String[] split = masterSrc.split(",");
                workDetailDTO.setMasterSrcList(Lists.newArrayList(split));
            }

            workDetailDTO.setAllowRefund(orderExtend.getAllowRefund());
            workDetailDTO.setWeChatScanUserId(orderExtend.getWeChatScanUserId());
        }

        /*产品下存在保修卡map*/
        Map<Long, Integer> warrantyMap = orderWarrantyBService.isExistWarrantyInfoMap(orderId, workId);

        /*产品列表*/
        List<OrderProduct> productList = orderProductService.listOrderProductByOrderId(orderId);
        workDetailDTO.setProductList(productList);

        /*价格表id*/
        if (CollectionUtil.isNotNullOrEmpty(productList)) {
            workDetailDTO.setTariffId(productList.get(0).getTariffId());
        }

        /*已选服务项列表*/
        List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderId);

        /*产品列表展开*/
        List<OrderProductExtend> orderProductExtends = orderProductExtendBService.getOrderProductExtend(orderId);
        if (CollectionUtil.isNotNullOrEmpty(orderProductExtends)) {
            List<OrderServiceItem> orderServItemListScr = new ArrayList<>(orderServiceItemList.size());
            orderProductExtends.forEach(orderProductExtend -> {
                orderProductExtend.setExistWarrantyInfo(warrantyMap.get(orderProductExtend.getProExtId()));
                orderServItemListScr.addAll(orderServiceItemList.stream().
                        filter(item->Objects.equals(item.getProExtId(),orderProductExtend.getProExtId())).
                        collect(Collectors.toList()));
            });

            /*已选服务项列表*/
            workDetailDTO.setOrderServiceItemList(orderServItemListScr);
        } else {
            /*已选服务项列表*/
            workDetailDTO.setOrderServiceItemList(orderServiceItemList);
        }

        workDetailDTO.setOrderProductExtends(orderProductExtends);

        workDetailDTO.setMeiTuanWriteOffStatus(GlobalConsts.NONE);
        /*优惠项列表*/
        List<OrderDiscount> discountList = orderDiscountService.listByOrderIdSrcMaster(orderId);
        if (discountList != null && discountList.size() > 0) {
            discountList.forEach(discount -> {
                discount.setCategName(DiscountTypeEnums.getSubName(discount.getCateg()));
            });
            Integer orderCoupDiscountAmount = discountList.stream()
                    .filter(item -> Objects.equals(item.getCateg(), DiscountTypeEnums.DISCOUNT_COUP_COMMON.getSubType())
                            || Objects.equals(item.getCateg(), DiscountTypeEnums.DISCOUNT_COUP_VOUCHER.getSubType())
                            || Objects.equals(item.getCateg(), DiscountTypeEnums.DISCOUNT_COUP_CASH.getSubType()))
                    .mapToInt(OrderDiscount::getAmount).sum();
            workDetailDTO.setOrderCoupDiscountAmount(orderCoupDiscountAmount);

            // 美团预约下单优惠
            workDetailDTO.setMeiTuanWriteOffStatus(discountList.stream()
                    .filter(e -> Objects.equals(e.getThirdCode(), GlobalConsts.NO)
                            && Objects.equals(e.getThirdCoupPlat(), ThirdPlatEnum.THIRD_COUP_TYPE_MT.getKey()))
                    .findFirst().map(e -> e.getWriteOffStatus()).orElse(0));

        } else {
            workDetailDTO.setOrderCoupDiscountAmount(0);


        }
        // 获取支付优惠明细
        if (NumberUtil.isNotNullOrZero(orderWork.getPayDiscountAmount())) {
            OrderDiscount orderDiscount = new OrderDiscount();
            orderDiscount.setOrderId(orderWork.getOrderId());
            orderDiscount.setAmount(orderWork.getPayDiscountAmount());
            orderDiscount.setType(OrderConsts.ORDER_DISCOUNT_TYPE_LIMIT_FREE);
            orderDiscount.setCategName("支付优惠");
            orderDiscount.setItemCode("");
            discountList.add(orderDiscount);
        }

        workDetailDTO.setOrderDiscountList(discountList);

        // 获取报价人信息
        OrderOperation orderOperation = orderOperationService.findBykey(orderWork.getOrderId());
        if (Objects.nonNull(orderOperation)) {
            boolean isUserQuotation = Lists.newArrayList(GlobalConsts.OPERATE_USER_TYPE_MASTER, GlobalConsts.OPERATE_USER_TYPE_USER).contains(orderOperation.getQuotationType());
            workDetailDTO.setUserOperationQuotation(isUserQuotation ? GlobalConsts.YES : GlobalConsts.NO);
        }
        // 是否确认过报价
        boolean haveConfirmQuotation = haveConfirmQuotation(orderWork.getOrderId());
        workDetailDTO.setHaveConfirmQuotation(haveConfirmQuotation ? GlobalConsts.YES : GlobalConsts.NO);

        /*已选配件列表*/
        List<OrderPart> orderPartList = orderPartService.listByOrderId(orderId);
        workDetailDTO.setOrderPartList(orderPartList);

        // 是否需要选择保修卡故障（1：否，2：是）
        boolean needSelectWarrantyFault = PremissUtil.needSelectWarrantyFault(orderDetail.getServCategId());
        workDetailDTO.setNeedSelectWarrantyFault(needSelectWarrantyFault ? GlobalConsts.YES : GlobalConsts.NO);

        // if (needSelectWarrantyFault) {
        /*已选保修项列表*/
        List<OrderWarrantyProduct> orderWarrantyProductList = orderWarrantyProductService.listByOrderId(orderId);
        if (CollectionUtil.isNotNullOrEmpty(orderWarrantyProductList) && orderWarrantyProductList.size() > 0) {
            orderWarrantyProductList.forEach(warrantyProduct -> {
                if (NumberUtil.isNotNullOrZero(warrantyProduct.getRuleId())) {
                    warrantyProduct.setRuleName(WarrantyRuleEnum.of(warrantyProduct.getRuleId()).getName());
                }
            });
        }
        workDetailDTO.setOrderWarrantyProductList(orderWarrantyProductList);
        // }

        // 需要完成码标志，1：否，2：是
        //workDetailDTO.setNeedSecurityCode(baseCodeService.needSecurityCode(plat, orderWork.getCityId(), agent) ?
        // GlobalConsts.YES : GlobalConsts.NO);
        // 保内才需要完成码
        workDetailDTO.setNeedSecurityCode(Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F) ? GlobalConsts.YES : GlobalConsts.NO);

        /*操作日志*/
        List<OrderLog> orderLogList = orderLogBService.findOrderLogsByMaster(orderId, (long) masterId);
        List<OrderTrack> orderTracks = orderTrackService.listOrderTrackByWorkIdSrcMaster(orderId, workId);
        if (orderTracks != null && !orderTracks.isEmpty()) {
            orderTracks.forEach(ot -> {
                if (ot.getAddUserId().equals(masterId) && Objects.nonNull(ot.getResultContent()) && !"".equals(ot.getResultContent())) {
                    OrderLog orderLog = new OrderLog();
                    orderLog.setTypeName("跟单结果");
                    StringBuilder sb = new StringBuilder(80);
                    if (Objects.nonNull(ot.getMapName())) {
                        sb.append(ot.getMapName()).append("，");
                    }
                    sb.append("结果：").append(ot.getResultContent());
                    orderLog.setContent(sb.toString());
                    orderLog.setCreateTime(ot.getCompleteTime() == null ? ot.getCreateTime() : ot.getCompleteTime());
                    orderLogList.add(orderLog);
                }
            });
            // 降序排序
            orderLogList.sort(Comparator.comparing(OrderLog::getCreateTime));
            Collections.reverse(orderLogList);
        }
        workDetailDTO.setOrderLogList(orderLogList);

        /*返修原单信息*/
        if (orderWork.getType() == OrderConsts.ORDER_TYPE_REWORK && orderWork.getOriginalId() != GlobalConsts.NONE) {
            ReworkDetailDTO reworkDetailDTO = this.getReworkDetail(orderWork.getOriginalId(), orderWork.getOriginalId(), orderWork.getMasterId());
            // F单隐藏退款入口
            if (!Objects.equals(workDetailDTO.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F)) {
                OrderDetail originalDetail = orderDetailService.findOrderDetailByKey(orderWork.getOriginalId());
                workDetailDTO.setSupportRefund(Objects.equals(originalDetail.getVvip(), GlobalConsts.YES) ? GlobalConsts.NO : GlobalConsts.YES);
            } else {
                workDetailDTO.setSupportRefund(GlobalConsts.NO);
            }

            workDetailDTO.setReworkDetail(reworkDetailDTO);
        }

        // 是否需要验券 1：否 2：是
        workDetailDTO.setNeedConsumeCoupon(getNeedConsumeCoupon(discountList, orderWork));

        //判断勤鸽天猫工单是否核销
        if (Objects.equals(OrderConsts.CHANNEL_ID_TMALL_WYG, orderWork.getChannelId())) {
            OrderTmallExtendQuery query = new OrderTmallExtendQuery();
            query.setOrderId(orderWork.getOrderId());
            query.setVerification(GlobalConsts.YES);
            OrderTmallExtend orderTmallExtend = orderTmallExtendService.findByTmallQuery(query);
            if (orderTmallExtend != null) {
                workDetailDTO.setVerification(GlobalConsts.YES);//已核销
            } else {
                workDetailDTO.setVerification(GlobalConsts.NONE);
            }
        }

        // 检查是否需要补全增值单信息
        log.info("#oms# vas isDataComplete req：{}", workId);
        com.zmn.common.dto2.ResponseDTO<Long> dataComplete = vasOrderListRemoteService.isDataComplete(workId);
        log.info("#oms# vas isDataComplete res：{}", dataComplete.toString());
        if (dataComplete.isSuccess()) {
            workDetailDTO.setReplenishVasFlag(GlobalConsts.YES);
            workDetailDTO.setReplenishVasOrderId(dataComplete.getData());
        } else {
            workDetailDTO.setReplenishVasFlag(GlobalConsts.NO);
        }

//        checkDaojia58ExtendInfo(orderWork, workDetailDTO);

        // 分润预估
        SharingEstimateVO sharingEstimate = null;
        try {
            sharingEstimate = orderWorkERPQueryBService.findSharingEstimate(orderId, workId, true, true);
            if (Objects.nonNull(sharingEstimate)) {
                workDetailDTO.setSharingEstimate(BeanMapper.map(sharingEstimate, WorkSharingEstimateDTO.class));
            }
        } catch (OmsBaseException e) {
            log.debug("工单[{}]无法获取分润信息:{}", workId, e.getMessage());
        }

        // 多次上门
        this.processOrderMultipleVisit(workDetailDTO, masterId, orderWork);

        // 订单标签处理
        this.processOrderTag(workDetailDTO);

        // 工单日程
        try {
            workDetailDTO.setProgramme(orderWorkProgrammeBService.getProgramme(workDetailDTO));
        } catch (Exception e) {
            log.error(String.format("工单[%s]获取日程信息错误", workDetailDTO.getWorkId()), e);
        }


        // 订单取消申请处理
        boolean canCancel = Objects.nonNull(confOrderChannelDRO) &&
                StringUtil.isNotBlank(confOrderChannelDRO.getWorkOrderCancelType()) &&
                StringUtil.convertStrsToList(confOrderChannelDRO.getWorkOrderCancelType())
                        .contains(ConfChannelWorkOrderTypeEnum.CONSTS_GCSAPP);
        if (canCancel) {
            this.processCancelApply(workDetailDTO);
        }

        // 服务完成时间限制
        Integer maxServiceMinutes = getMaxServiceMinutes(orderWork, orderServiceItemList);
        workDetailDTO.setMaxServiceMinutes(maxServiceMinutes);

        // 订单验收处理
        this.processOrderAcceptance(workDetailDTO);

        // 是否需要验收
        workDetailDTO.setHasAcceptance(GlobalConsts.NONE);
        workDetailDTO.setNeedAcceptance(GlobalConsts.NO);
        if (Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_C)) {
            log.debug("[{}]获取渠道验收配置入参：【{}-{}-{}-{}-{}】", orderWork.getOrderId(), orderWork.getChannelId(), orderWork.getCityId(), 7, orderWork.getServCategId(), orderWork.getShowCategId());
            PilotCheckQuery query = new PilotCheckQuery();
            query.setPilotTypeId(PilotTypeEnum.SERVICE_ACCEPTANCE.getId());
            query.setServCategId(orderWork.getServCategId());
            query.setCategId(orderWork.getShowCategId());
            query.setChannelId(orderWork.getChannelId());
            query.setCityId(orderWork.getCityId());
            log.info("pilotRemoteService.checkPilotByQuery query={}", query);
            ResponseDTO<Boolean> channelResponse = pilotRemoteService.checkPilotByQuery(query);
            log.info("pilotRemoteService.checkPilotByQuery channelResponse={}", channelResponse);
            log.debug("[{}]获取渠道验收配置出参：【{}】", orderWork.getOrderId(), JSON.toJSONString(channelResponse));
            if (channelResponse.isSuccess() && Objects.nonNull(channelResponse.getData())) {
                workDetailDTO.setHasAcceptance(channelResponse.getData() ? GlobalConsts.NO : GlobalConsts.NONE);
                workDetailDTO.setNeedAcceptance(channelResponse.getData() ? GlobalConsts.YES : GlobalConsts.NO);
            }
        }

        // 计价器3.0必须验收
        if (Objects.equals(workDetailDTO.getServItemType(), OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE)) {
            workDetailDTO.setNeedAcceptance(GlobalConsts.YES);
            // 计价器3.0 不修了，就不需要验收
            OrderQuotationProcess dbProcess = orderQuotationProcessService.findByOrderId(orderId);
            if (dbProcess != null && !Objects.equals(dbProcess.getAgreeStatus(), GlobalConsts.YES)) {
                // 不同意维修
                workDetailDTO.setNeedAcceptance(GlobalConsts.NO);
            }
        }


        // 是否发起收款--多次上门
        // 当前上门状态是已上门、工单金额不是0、服务分类是防水补漏和墙面翻新
        workDetailDTO.setMultipleAmount(GlobalConsts.NO);
        workDetailDTO.setDeliveryWaitPart(GlobalConsts.NO);
        if (Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_VISIT)
                && NumberUtil.isNotNullOrZero(orderWork.getOriginalAmount())) {
            if (Objects.equals(orderWork.getServCategId(), ProductConsts.SERV_CATEG_WATERPROOF)
                    || Objects.equals(orderWork.getServCategId(), ProductConsts.SERV_CATEG_METOPE)
                    || Objects.equals(orderWork.getServCategId(), ProductConsts.SERV_CATEG_KITCHEN_TOILET)) {
                workDetailDTO.setMultipleAmount(GlobalConsts.YES);
            } else {
                workDetailDTO.setDeliveryWaitPart(GlobalConsts.YES);
            }
        }

        if (!CollectionUtil.isNullOrEmpty(productList) && Objects.nonNull(workDetailDTO.getDutyTime())) {
            // 预约时间结束时间
            log.info("servAssCategoryListRemoteService#getProductGroupByShowCategId 查询产品分组 入参：servCateg={}, categTwoId={}", workDetailDTO.getServCategId(), orderWork.getShowCategId());
            CategProductGroupQuery categProductGroupQuery = new CategProductGroupQuery();
            categProductGroupQuery.setBizType(orderWork.getBizType());
            categProductGroupQuery.setCategId(orderWork.getShowCategId());
            categProductGroupQuery.setServCategId(workDetailDTO.getServCategId());
            categProductGroupQuery.setShowType(BaseProductConsts.EC_SHOW_TYPE);
            ResponseDTO<CategProductGroupDRO> productGroupDro = categServProductListRemoteService.getBasisProductGroupByQuery(categProductGroupQuery);
            log.info("servAssCategoryListRemoteService#getProductGroupByShowCategId 查询产品分组 出参：【{}】", productGroupDro);
            CategProductGroupDRO categorySimpleProductGroupDRO = productGroupDro.getData();
            Integer productGroupCode = 0;
            if (categorySimpleProductGroupDRO != null) {
                productGroupCode = categorySimpleProductGroupDRO.getGroupCode();
            }
            ResponseDTO<Pair<Integer, Integer>> pairResponseDTO = stockListRemoteService.getServTimeByEngineerAndProductGroupCode(masterId, productGroupCode, productList.get(0).getNumber());
            if (pairResponseDTO.isSuccess()) {
                Integer serverDuration = pairResponseDTO.getData().getValue();
                Date dutyTimeEnd = DateUtil.addMinute(workDetailDTO.getDutyTime(), serverDuration);
                workDetailDTO.setDutyTimeEnd(dutyTimeEnd);
            }
        }

        // 工程师是否提交验收检测项目
        workDetailDTO.setAcceptMaintainStatus(GlobalConsts.NO);
        List<OrderAcceptMaintainItem> itemList = orderAcceptMaintainItemService.listByOrderIdAndWorkId(orderWork.getOrderId(), orderWork.getWorkId());
        if (CollectionUtil.isNotNullOrEmpty(itemList)) {
            workDetailDTO.setAcceptMaintainStatus(GlobalConsts.YES);
            if (Objects.equals(workDetailDTO.getPaymentAcceptanceResultStatus(), OrderConsts.ORDER_ACCEPTANCE_STATUS_FAIL)
                    && Objects.nonNull(workDetailDTO.getPaymentOperateTime())
                    && workDetailDTO.getPaymentOperateTime().getTime() > itemList.get(0).getCreateTime().getTime()) {
                workDetailDTO.setAcceptMaintainStatus(GlobalConsts.NO);
            }
        }

        // 处理服务项关联配件二级分类
        if (Objects.equals(orderWork.getServItemType(), OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE) && CollectionUtil.isNotNullOrEmpty(orderServiceItemList)) {
            List<Integer> serviceItemIdList = orderServiceItemList
                    .stream()
                    .map(OrderServiceItem::getServItemId)
                    .collect(Collectors.toList());
            log.info("serviceItemListRemoteService.getItemPartByItemId serviceItemIdList={}", serviceItemIdList);
            ResponseDTO<List<ItemPartsDRO>> itemPartResponse = itemPartsRemoteService.listItemPartByItemIds(serviceItemIdList);
            log.info("serviceItemListRemoteService.getItemPartByItemId itemPartResponse={}", JSON.toJSONString(itemPartResponse));
            if (CollectionUtil.isNotNullOrEmpty(itemPartResponse.getData())) {
                List<Integer> partSubCategoryIdList = itemPartResponse.getData()
                        .stream()
                        .map(ItemPartsDRO::getPartSubCategoryId)
                        .collect(Collectors.toList());
                workDetailDTO.setPartSubCategTwoIdList(partSubCategoryIdList);
            }
        }

        // 处理预估收入
        workDetailDTO.setForecastTotalAmount(this.getForecastTotalAmount(orderWork));

        return workDetailDTO;
    }

    /**
     * 处理邀评价
     *
     * @param workDetailDTO
     * @param confOrderChannelDRO
     */
    private void processInviteComment(WorkDetailDTO workDetailDTO, ConfOrderChannelDRO confOrderChannelDRO) {
        // 渠道是否需要邀评，1：否，2：是
        workDetailDTO.setNeedGuideInviteComment(confOrderChannelDRO.getInviteComment());
        if (!Objects.equals(confOrderChannelDRO.getInviteComment(), GlobalConsts.YES)) {
            return;
        }
        // 好评奖励金
        try {
            ResponseDTO<Integer> commentBonusOfOrder = cmtCommentApiListRemoteService.getCommentBonusOfOrder(workDetailDTO.getOrderId());
            Integer commentBonus = commentBonusOfOrder.getData();
            log.info("工单{}详情获取邀评奖励金出参: {}", workDetailDTO.getOrderId(), commentBonusOfOrder);
            if (NumberUtil.isNullOrZero(commentBonus)) {
                return;
            }
            StringBuilder sb = new StringBuilder();
            String appPlat = StringUtils.defaultString(confOrderChannelDRO.getInviteCommentPlat());
            sb.append(String.format("立即邀请用户到%s上好评", appPlat));
            sb.append(String.format("，可获得%s元奖励", NumberUtil.convertMoneyToYuan2(commentBonus)));
            workDetailDTO.setInviteCommentInfo(sb.toString());
            log.info("工单{}详情获取邀评奖励金字符串拼接:{}",workDetailDTO.getOrderId(),sb.toString());
        } catch (Exception e) {
            log.error("工单详情获取邀评奖励金错误", e);
        }
    }

    /**
     * 取消申请处理
     *
     * @param workDetailDTO
     */
    private void processCancelApply(WorkDetailDTO workDetailDTO) {
        // 详情增加待取消标识
        MasterWorking masterWorking = masterWorkingService.findMasterWorkingByWorkId(workDetailDTO.getWorkId());
        if (Objects.nonNull(masterWorking)) {
            workDetailDTO.setWaitCancel(masterWorking.getWaitCancel());
        }

        if (!Objects.equals(workDetailDTO.getWaitCancel(), GlobalConsts.YES)) {
            return;
        }

        //查询申请取消工单信息
        OrderCancelApplyQuery orderCancelApplyQuery = new OrderCancelApplyQuery();
        orderCancelApplyQuery.setOrderId(workDetailDTO.getOrderId());
        orderCancelApplyQuery.setWorkId(workDetailDTO.getWorkId());
        orderCancelApplyQuery.setReviewStatusList(Lists.newArrayList(CancelApplyConsts.ORDER_REVIEW_STATUS_CHECK, CancelApplyConsts.ORDER_REVIEW_STATUS_CHECK_PROCESSING));
        orderCancelApplyQuery.setSearchReason(GlobalConsts.YES);
        log.info("orderCancelApplyListRemoteService.listCancelApplyByQuery query={}", orderCancelApplyQuery);
        ResponseDTO<List<OrderCancelApplyDRO>> dto = orderCancelApplyListRemoteService.listCancelApplyByQuery(orderCancelApplyQuery);
        log.info("orderCancelApplyListRemoteService.listCancelApplyByQuery dto={}", dto);
        if (CollectionUtil.isNotNullOrEmpty(dto.getData())) {
            workDetailDTO.setShowWaitCancelModule(true);
            OrderCancelApplyDRO orderCancelApplyDRO = dto.getData().get(0);
            workDetailDTO.setCancelApplyTime(orderCancelApplyDRO.getCreateTime());

            if (CollectionUtil.isNotNullOrEmpty(orderCancelApplyDRO.getCancelReasonList())) {
                OrderCancelReasonDRO cancelApplyReasonBO = orderCancelApplyDRO.getCancelReasonList()
                        .stream()
                        .filter(e -> Objects.equals(e.getReasonSource(), CancelApplyConsts.CANCEL_APPLY_REASON_SOURCE_APPLY))
                        .findAny()
                        .orElse(null);
                if (Objects.nonNull(cancelApplyReasonBO)) {
                    workDetailDTO.setCancelApplyRemark(cancelApplyReasonBO.getMapName());
                    workDetailDTO.setCancelApplyContent(cancelApplyReasonBO.getContent());
                }
            }

            boolean isMasterReview = dto.getData()
                    .stream()
                    .anyMatch(e -> Objects.equals(e.getReviewUserType(), GlobalConsts.OPERATE_USER_TYPE_MASTER));
            if (isMasterReview) {
                workDetailDTO.setCancelApplyUserType(GlobalConsts.OPERATE_USER_TYPE_USER);
                Date autoCancelTime = workTrackBService.getAutoCancelTime(orderCancelApplyDRO.getCreateTime());
                if (Objects.isNull(autoCancelTime)) {
                    return;
                }
                workDetailDTO.setAutoCancelTime(autoCancelTime);
                workDetailDTO.setCancelApplyTips(String.format("请在%s前与用户核实，否则系统将自动取消订单", DateUtil.toString(autoCancelTime, "HH:mm:ss")));
            }

        } else {
            OrderWorkTrack masterWaitCancelTrack = workTrackBService.getMasterWaitCancelTrack(workDetailDTO.getOrderId(), workDetailDTO.getWorkId());
            if (masterWaitCancelTrack == null) {
                return;
            }

            // 查询跟单取消缘由
            TrackWorkQuery query = new TrackWorkQuery();
            query.setOrderId(workDetailDTO.getOrderId());
            query.setWorkId(workDetailDTO.getWorkId());
            query.setTrackContentIdList(TrackConfigConsts.TRACK_CONTENT_ID_CANCEL);
//            query.setTrackWorkId(masterWaitCancelTrack.getTrackId());
            ResponseDTO<List<TrackWorkDRO>> listResponseDTO = trackWorkListRemoteService.listTrackByQuery(query);
            if (CollectionUtils.isEmpty(listResponseDTO.getData())) {
                return;
            }
            TrackWorkDRO trackWorkDRO = listResponseDTO.getData().get(0);
            workDetailDTO.setCancelApplyUserType(GlobalConsts.OPERATE_USER_TYPE_USER);
            workDetailDTO.setCancelApplyTime(trackWorkDRO.getCreateTime());
            workDetailDTO.setCancelApplyRemark(trackWorkDRO.getReasonName());

            Date autoCancelTime = workTrackBService.getAutoCancelTime(trackWorkDRO.getCreateTime());
            if (Objects.isNull(autoCancelTime)) {
                return;
            }
            workDetailDTO.setAutoCancelTime(autoCancelTime);
            workDetailDTO.setCancelApplyTips(String.format("请在%s前与用户核实，否则系统将自动取消订单", DateUtil.toString(autoCancelTime, "HH:mm:ss")));
        }
    }

    /**
     * 订单标签处理
     *
     * @param workDetailDTO
     */
    private void processOrderTag(WorkDetailDTO workDetailDTO) {
        List<OrderTag> orderTagList = orderTagService.listOrderTagByOrderIdList(Lists.newArrayList(workDetailDTO.getOrderId()));
        // 过滤优质订单及高价值用户
        List<OrderTag> tagListFilter = null;
        if (CollectionUtil.isNotNullOrEmpty(orderTagList)) {
            tagListFilter = orderTagList.stream().filter(tag -> {
                boolean needFilter = Objects.equals(tag.getTagId(), OrderTagConsts.USER_TAG_ID_HIGH_VALUE) ||
                        Objects.equals(tag.getTagId(), OrderTagConsts.TAG_ID_HIGH_VALUE_USER) ||
                        Objects.equals(tag.getTagId(), OrderTagConsts.TAG_ID_HIGH_QUALITY);
                return !needFilter;
            }).collect(Collectors.toList());
        }
        if (CollectionUtil.isNotNullOrEmpty(tagListFilter)) {
            // 标签
            workDetailDTO.setTagList(BeanMapper.mapList(tagListFilter, WorkTagDTO.class));

            // 高价值用户标签
            boolean isHighValueUser = tagListFilter.stream()
                    .anyMatch(tag -> Objects.equals(tag.getTagId(), OrderTagConsts.USER_TAG_ID_HIGH_VALUE) || Objects.equals(tag.getTagId(), OrderTagConsts.TAG_ID_HIGH_VALUE_USER)
                    );
            workDetailDTO.setHighValueUser(isHighValueUser ? GlobalConsts.YES : GlobalConsts.NO);
        }

        if (CollectionUtil.isNullOrEmpty(workDetailDTO.getTagList())) {
            workDetailDTO.setTagList(Lists.newArrayList());
        }
        if (Objects.nonNull(workDetailDTO.getNeedGuideInviteComment()) &&
                Objects.equals(workDetailDTO.getNeedGuideInviteComment(), GlobalConsts.YES)) {
            WorkTagDTO workTagDTO = new WorkTagDTO();
            workTagDTO.setTagId(OrderTagConsts.TAG_ID_CHANNEL_INVITE);
            workTagDTO.setTagName(OrderTagConsts.getTagName(OrderTagConsts.TAG_ID_CHANNEL_INVITE));
            workDetailDTO.getTagList().add(workTagDTO);
        }

        if (workDetailDTO.getServItemType() == OrderConsts.SERVICE_ITEM_TYPE_ADVANCE_PAY) {
            WorkTagDTO workTagDTO = new WorkTagDTO();
            workTagDTO.setTagId(OrderTagConsts.TAG_ID_WORK_ADVANCE_PAY);
            workTagDTO.setTagName(OrderTagConsts.getTagName(OrderTagConsts.TAG_ID_WORK_ADVANCE_PAY));
            workDetailDTO.getTagList().add(workTagDTO);
        }

        if (servItemBService.isQuotationThreeType(workDetailDTO.getServItemType(), workDetailDTO.getFinalPrice())) {
            WorkTagDTO workTagDTO = new WorkTagDTO();
            workTagDTO.setTagId(OrderTagConsts.TAG_ID_WORK_QUOTATION_THREE);
            workTagDTO.setTagName(OrderTagConsts.getTagName(OrderTagConsts.TAG_ID_WORK_QUOTATION_THREE));
            workDetailDTO.getTagList().add(workTagDTO);
        }
    }

    /**
     * 多次上门处理
     *
     * @param workDetailDTO
     */
    private void processOrderMultipleVisit(WorkDetailDTO workDetailDTO, Integer masterId, OrderWork orderWork) {
        workDetailDTO.setShowDeposit(GlobalConsts.YES);
        // 查询上门记录
        List<OrderVisit> orderVisitList = orderVisitService.listByOrderIdSrcMaster(workDetailDTO.getOrderId());
        if (CollectionUtil.isNullOrEmpty(orderVisitList)) {
            if (NumberUtil.isNotNullOrZero(orderWork.getDepositAmount())) {
                AmountDTO amountDTO = new AmountDTO();
                amountDTO.setAcceptanceId(0L);
                amountDTO.setVisitId(0L);
                amountDTO.setOrderPayId(0L);
                amountDTO.setAmount(orderWork.getDepositAmount());
                amountDTO.setAmountType(OrderPayConsts.ORDER_PAY_DEPOSIT);
                amountDTO.setPayStatus(orderWork.getDepositStatus());
                workDetailDTO.setAmountList(Lists.newArrayList(amountDTO));
            }

            /*List<OrderPay> orderPayList = orderPayService.listOrderPayByOrderIdAndWorkIdMasterSrc(workDetailDTO.getOrderId(), workDetailDTO.getWorkId());
            if (CollectionUtil.isNotNullOrEmpty(orderPayList)) {
                OrderPay orderPay = orderPayList.stream().filter(item -> Objects.equals(item.getAmountType(), OrderPayConsts.ORDER_PAY_DEPOSIT) &&
                        Objects.equals(item.getPayStatus(), PayConsts.PAY_STATUS_DONE) && Objects.equals(item.getDuplicate(), GlobalConsts.NO)).findFirst().orElse(null);
                if (orderPay != null) {
                    AmountDTO amountDTO = new AmountDTO();
                    amountDTO.setAcceptanceId(0L);
                    amountDTO.setVisitId(0L);
                    amountDTO.setOrderPayId(0L);
                    amountDTO.setAmount(orderPay.getAmount());
                    amountDTO.setAmountType(orderPay.getAmountType());
                    amountDTO.setPayStatus(orderPay.getPayStatus());
                    workDetailDTO.setAmountList(Lists.newArrayList(amountDTO));
                }
            }*/
            return;
        }

        List<OrderVisitDTO> orderVisitDTOList = BeanMapper.mapList(orderVisitList, OrderVisitDTO.class);
        List<OrderVisitDTO> resultDTOList = orderVisitDTOList.stream()
                .filter(e -> !Objects.equals(e.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_CANCEL))
                .collect(Collectors.toList());
        workDetailDTO.setOrderVisitList(resultDTOList);

        List<AmountDTO> amountDTOList = Lists.newArrayListWithCapacity(orderVisitList.size());

        orderVisitList.forEach(orderVisit -> {
            // 过滤已取消的上门
            if (Objects.equals(orderVisit.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_CANCEL)) {
                if (Objects.equals(orderVisit.getPayStatus(), PayConsts.PAY_STATUS_NONE)) {
                    return;
                }
            }
            AmountDTO amountDTO = new AmountDTO();
            amountDTO.setAcceptanceId(orderVisit.getAcceptanceId());
            amountDTO.setVisitId(orderVisit.getVisitId());
            amountDTO.setOrderPayId(orderVisit.getOrderPayId());
            amountDTO.setAmount(orderVisit.getAmount());
            amountDTO.setAmountType(orderVisit.getAmountType());
            if (NumberUtil.isNullOrZero(orderVisit.getOrderPayId()) && NumberUtil.isNullOrZero(orderVisit.getAcceptanceId())) {
                amountDTO.setPayStatus(PayConsts.PAY_STATUS_DONE);
            } else {
                amountDTO.setPayStatus(orderVisit.getPayStatus());
            }
            amountDTOList.add(amountDTO);
        });

        OrderVisit orderVisit = Streams.findLast(orderVisitList.stream()
                        .filter(item -> !Objects.equals(item.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_CANCEL)
                                && Objects.equals(item.getMasterId(), masterId)))
                .orElse(null);
        if (Objects.nonNull(orderVisit)) {
            workDetailDTO.setDutyTime(orderVisit.getExpectVisitTime());
            workDetailDTO.setMultipleVisitStatus(orderVisit.getVisitStatus());
            if (NumberUtil.isNullOrZero(orderVisit.getOrderPayId())
                    && NumberUtil.isNullOrZero(orderVisit.getAcceptanceId())) {
                workDetailDTO.setMultiplePayStatus(PayConsts.PAY_STATUS_DONE);
            } else {
                workDetailDTO.setMultiplePayStatus(orderVisit.getPayStatus());
            }
        }
        // 定金按钮展示
        OrderVisit deposit = Streams.findLast(orderVisitList.stream()
                        .filter(item -> !Objects.equals(item.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_CANCEL)
                                && Objects.equals(item.getAmountType(), OrderPayConsts.ORDER_PAY_DEPOSIT)))
                .orElse(null);
        if (Objects.nonNull(deposit)) {
            workDetailDTO.setShowDeposit(GlobalConsts.NO);
        }

        Integer waitPay = amountDTOList.stream()
                .filter(e -> Objects.equals(e.getPayStatus(), PayConsts.PAY_STATUS_NONE))
                .mapToInt(AmountDTO::getAmount).sum();
        workDetailDTO.setMasterAmount(Optional.ofNullable(workDetailDTO.getMasterAmount()).orElse(0) - waitPay);
        workDetailDTO.setAmountList(amountDTOList);
    }

    /**
     * 订单验收处理
     *
     * @param workDetailDTO
     */
    private void processOrderAcceptance(WorkDetailDTO workDetailDTO) {
        OrderWorkAcceptanceDbQuery query = new OrderWorkAcceptanceDbQuery();
        query.setOrderId(workDetailDTO.getOrderId());
        query.setWorkId(workDetailDTO.getWorkId());
        List<OrderWorkAcceptance> acceptanceList = orderWorkAcceptanceService.listOrderWorkAcceptanceByQuerySrcMaster(query);
        if (CollectionUtil.isNullOrEmpty(acceptanceList)) {
            workDetailDTO.setPaymentAcceptanceResultStatus(GlobalConsts.NONE);
            return;
        }
        acceptanceList = acceptanceList.stream()
                .filter(e -> Objects.equals(e.getAcceptanceType(), OrderConsts.ORDER_ACCEPTANCE_TYPE_PAYMENT)
                        || Objects.equals(e.getAcceptanceType(), OrderConsts.ORDER_ACCEPTANCE_TYPE_PAYMENT_CONFIRM))
                .collect(Collectors.toList());
        if (CollectionUtil.isNullOrEmpty(acceptanceList)) {
            workDetailDTO.setPaymentAcceptanceResultStatus(GlobalConsts.NONE);
            return;
        }

        // 最新的尾款验收
        workDetailDTO.setPaymentAcceptanceResultStatus(acceptanceList.get(0).getAcceptanceResultStatus());
        workDetailDTO.setPaymentAcceptanceId(acceptanceList.get(0).getAcceptanceId());
        workDetailDTO.setPaymentOperateTime(acceptanceList.get(0).getOperateTime());
    }

    // 小号绑定处理
    private void processXNOBindStatus(OrderDetail orderDetail, OrderWork orderWork, WorkDetailDTO workDetailDTO) {

        Integer bindStatus = orderDetail.getBindStatus();
        if (orderDetail.getBindStatus() != 0) {

            log.debug("processXNOBindStatus#getEngineerById 入参 [{}]",orderWork.getMasterId());
            ResponseDTO<ForeignEngineerBasicInfoDRO> engineerByEngineerId = engineerListRemoteService.getEngineerById(orderWork.getMasterId());
            log.debug("processXNOBindStatus#getEngineerById 出参 [{}]",JSON.toJSONString(engineerByEngineerId));
            String mobile = "";
            if (engineerByEngineerId.getData() != null && engineerByEngineerId.isSuccess()) {
                mobile = engineerByEngineerId.getData().getMobile();
            }

            String bindTelephone = orderDetail.getTelephone();
            ZsXnoBindVO zsXnoBindVO = orderXnoBindService.queryXNO(mobile, orderDetail.getTelephone(), orderWork);
            if (zsXnoBindVO != null) {
                boolean bindStatus1 = this.getXnoBindStatus(zsXnoBindVO.getXno(), zsXnoBindVO.getStatus());
                bindTelephone = bindStatus1 ? zsXnoBindVO.getXno() : orderDetail.getTelephone();
            }
            workDetailDTO.setTelephone(bindTelephone);

            if (StringUtils.isNotBlank(orderDetail.getTelephone2())) {
                String bindTelephone2 = orderDetail.getTelephone2();
                ZsXnoBindVO zsXnoBindVO2 = orderXnoBindService.queryXNO(mobile, orderDetail.getTelephone2(), orderWork);
                if (zsXnoBindVO2 != null) {
                    boolean bindStatus2 = this.getXnoBindStatus(zsXnoBindVO2.getXno(), zsXnoBindVO2.getStatus());
                    bindTelephone2 = bindStatus2 ? zsXnoBindVO2.getXno() : orderDetail.getTelephone2();
                }
                workDetailDTO.setTelephone2(bindTelephone2);
            }
            if (StringUtils.isNotBlank(orderDetail.getTelephone3())) {
                String bindTelephone3 = orderDetail.getTelephone3();
                ZsXnoBindVO zsXnoBindVO3 = orderXnoBindService.queryXNO(mobile, orderDetail.getTelephone3(), orderWork);
                if (zsXnoBindVO3 != null) {
                    boolean bindStatus3 = this.getXnoBindStatus(zsXnoBindVO3.getXno(), zsXnoBindVO3.getStatus());
                    bindTelephone3 = bindStatus3 ? zsXnoBindVO3.getXno() : orderDetail.getTelephone3();
                }
                workDetailDTO.setTelephone3(bindTelephone3);
            }

            workDetailDTO.setBindMasterMobile(mobile);

        }
        workDetailDTO.setBindStatus(bindStatus);

    }

    /**
     * 获取小号的绑定状态
     */
    private boolean getXnoBindStatus(String xno, Integer status) {
        if (!Objects.equals(status, OrderConsts.BIND_STATUS_BIND)) {
            return false;
        }
        if (StringUtils.isBlank(xno)) {
            return false;
        }

        try {
            // 查询小号是否显示真实号码
            ResponseDTO<Boolean> isShowXno = xnoRemoteService.queryExposeByXno(xno);
            log.info("com.zmn.oms.business.impl.work.masterwork.MasterWorkBServiceImpl.getXnoBindStatus 查询小号是否显示真实号码出参{}", isShowXno);
            if (isShowXno.isSuccess() && isShowXno.getData() != null) {
                return !isShowXno.getData();
            }
            return false;
        } catch (Exception e) {
            log.info("com.zmn.oms.business.impl.work.masterwork.MasterWorkBServiceImpl.getXnoBindStatus error {}", e);
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 服务完成时间限制
     *
     * @param orderWork
     * @param orderServiceItemList
     */
    private int getMaxServiceMinutes(OrderWork orderWork, List<OrderServiceItem> orderServiceItemList) {

        int maxServiceMinutes = 0;
        // 啄木鸟平台-计价器产品订单 限制完成时间 15分钟
        if (Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_ZMN) && servItemBService.isQuotationType(orderWork.getServItemType())) {
            // 如果用户不修了，订单只收取了上门费、晚间加急费、深夜加急费三种费用中任意一种，订单可直接完成。
            long count = orderServiceItemList.stream().filter(e -> "其他收费".equals(e.getServItemGroupName())
                    || "其他服务".equals(e.getServItemGroupName())).count();
            // 服务项是否仅包含用户不修了
            boolean unRepair = count == orderServiceItemList.size();
            // 匹配名称
            String matchName1 = "上门费";
            String matchName2 = "晚间加急费";
            String matchName3 = "深夜加急费";
            boolean present = orderServiceItemList.stream().anyMatch(e -> e.getServItemName().contains(matchName1)
                    || e.getServItemName().contains(matchName2) || e.getServItemName().contains(matchName3));
            List<Integer> collect = orderServiceItemList.stream().map(OrderServiceItem::getServItemId).collect(Collectors.toList());
            boolean unNeedQuery = orderWork.getProductId() == 0 || CollectionUtil.isNullOrEmpty(collect);

            if (Objects.equals(orderWork.getServItemType(), OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE)) {
                OrderQuotationProcess process = orderQuotationProcessService.findByOrderId(orderWork.getOrderId());
                if (Objects.nonNull(process) && Objects.equals(process.getAgreeStatus(), GlobalConsts.NO)) {
                    log.info("计价器3.0订单已不同意维修，最大服务时长置为0");
                    return 0;
                }
            }

            Integer limitTime = null;
            if (CollectionUtils.isNotEmpty(collect)) {
                // 完成时间读取配置
                log.info("orderId:[{}] getMaxServiceMinutes dio:companyId:{} , itemIdList:{}", orderWork.getWorkId(), orderWork.getCompanyId(), collect);
                ResponseDTO<Integer> maxServiceMinutesDTO = itemTimeRemoteService.getMaxServiceMinutes(collect, orderWork.getCompanyId());
                log.info("orderId:[{}] getMaxServiceMinutes dro:{}", orderWork.getWorkId(), JSONObject.toJSONString(maxServiceMinutesDTO));
                if (maxServiceMinutesDTO.isSuccess()) {
                    limitTime = maxServiceMinutesDTO.getData();
                }
            }

            if (Objects.isNull(limitTime)) {
                return 0;
            }

            if (unRepair && present || unNeedQuery) {
                maxServiceMinutes = 0;
            } else {
                // 2.4号早上8点之前上门的计价器订单，完成时间的规则和上版本保持一致（读取时间配置项）
                Date date = DateUtil.dateFormatToDate("2021-02-04 08:00:00", DateUtil.FORMAT_DEFAULT);
                if (Objects.nonNull(orderWork.getVisitTime())) {
                    if (orderWork.getVisitTime().before(date)) {
                        if (Objects.isNull(limitTime)) {
                            maxServiceMinutes = 0;
                        } else {
                            // 根据上门时间计算剩余时间
                            long timespan = DateUtil.getTimespan(orderWork.getVisitTime(), DateUtil.getNow(), DateUtil.UNIT_MINUTE);
                            maxServiceMinutes = limitTime - (int) timespan;
                        }
                    } else {
                        List<OrderLog> logList = orderLogBService.findOrderLogsByOrderId(orderWork.getOrderId());
                        // 派单撤回、分单撤回、改派后时间重新计算
                        // 查询最新一次派单撤回或分单撤回时间
                        long backTime = 0L;
                        Optional<OrderLog> backLog = logList.stream().filter(e -> Objects.equals(e.getType(), OrderLogConsts.ORDER_LOG_TYPE_DISTRIBUTE_BACK)
                                        || Objects.equals(e.getType(), OrderLogConsts.ORDER_LOG_TYPE_ASSIGN_BACK))
                                .max(Comparator.comparing(OrderLog::getCreateTime));
                        if (backLog.isPresent()) {
                            backTime = backLog.get().getCreateTime().getTime();
                        }
                        // 最后一次改派时间
                        OrderChangeRecord changeRecord = orderChangeRecordService.getChangeRecordByOrderId(orderWork.getOrderId());
                        if (Objects.nonNull(changeRecord) && NumberUtil.isNotNullOrZero(changeRecord.getDistributeCount())) {
                            long distributeBackTime = changeRecord.getLastDistributeTime().getTime();
                            backTime = Math.max(distributeBackTime, backTime);
                        }

                        long finalTime = backTime;
                        // 首次打开计价器时间
                        Optional<OrderLog> firstQuotation = logList.stream().filter(e -> Objects.equals(e.getType(), OrderLogConsts.ORDER_LOG_TYPE_QUOTATION_START)
                                && (e.getCreateTime().getTime() > finalTime)).min(Comparator.comparing(OrderLog::getCreateTime));
                        // 后台报价时间
                        Optional<OrderLog> backgroundQuotation = logList.stream().filter(e -> Objects.equals(e.getType(), OrderLogConsts.ORDER_LOG_TYPE_SERVICEITEM)
                                && (e.getCreateTime().getTime() > finalTime)).min(Comparator.comparing(OrderLog::getCreateTime));

                        // 起始时间（优先取首次打开计价器时间，两者都存在取最早时间计算）
                        Date startTime = null;
                        if (firstQuotation.isPresent()) {
                            startTime = firstQuotation.get().getCreateTime();
                        } else if (backgroundQuotation.isPresent()) {
                            startTime = backgroundQuotation.get().getCreateTime();
                        }

                        if (firstQuotation.isPresent() && backgroundQuotation.isPresent()) {
                            Date firstQuotationDate = firstQuotation.get().getCreateTime();
                            Date backgroundDate = backgroundQuotation.get().getCreateTime();
                            startTime = firstQuotationDate.getTime() < backgroundDate.getTime() ? firstQuotationDate : backgroundDate;
                        }

                        if (Objects.equals(orderWork.getServItemType(), OrderConsts.SERVICE_ITEM_TYPE_QUOTATION_THREE)) {
                            OrderQuotationProcess process = orderQuotationProcessService.findByOrderId(orderWork.getOrderId());
                            if (Objects.nonNull(process) && Objects.nonNull(process.getStartCheckTime())) {
                                startTime = process.getStartCheckTime();
                            }
                        }
                        // 已过时间
                        long timespan = 0;
                        if (Objects.nonNull(startTime)) {
                            timespan = DateUtil.getTimespan(startTime, DateUtil.getNow(), DateUtil.UNIT_SECOND);
                        } else {
                            // 起始时间为空取上门时间计算
                            timespan = DateUtil.getTimespan(orderWork.getVisitTime(), DateUtil.getNow(), DateUtil.UNIT_SECOND);
                        }
                        timespan = timespan / 60;
                        int time = 0;
                        if (Objects.nonNull(limitTime)) {
                            time = limitTime - (int) timespan;
                        }
                        log.info("orderId:{} 完成限制 time:{}", orderWork.getOrderId(), time);
                        maxServiceMinutes = time;
                    }
                }
            }
        }
        return maxServiceMinutes;
    }

    /**
     * 获取是否可以验券
     *
     * @param discountList
     * @param orderWork
     * @return
     */
    private Integer getNeedConsumeCoupon(List<OrderDiscount> discountList, OrderWork orderWork) {

        // 优惠券为空 可以验券
        if (CollectionUtils.isEmpty(discountList)) {
            return GlobalConsts.YES;
        }

        // 已使用优惠券不能再验券
        boolean usedConpon = discountList.stream()
                .anyMatch(e -> Objects.equals(e.getCateg(), FicoConsts.ORDER_IN_DISCOUNT_CATEG_COUPON));
        if (usedConpon) {
            return GlobalConsts.NO;
        } else {
            return GlobalConsts.YES;
        }
        // // 1、校验是否可以自动选择优惠券使用
        // // A. 使用外部优惠券后，订单不可使用优惠券
        // // B. 下单的时候用了优惠券，则APP端或者后台则不能再使用优惠券（包含外部券）
        // Optional<OrderDiscount> orderDiscountOptional = discountList.stream().filter(e -> Objects.equals(e.getCateg(), DiscountConsts.DISCOUNT_CATEG_COUPON)).findFirst();
        // if (!orderDiscountOptional.isPresent()) {
        //     return GlobalConsts.YES;
        // }
        //
        //
        // // B 优惠券创建时间 和 订单创建时间小于三秒 认为是下单时候用的优惠券
        // OrderDiscount orderDiscount = orderDiscountOptional.get();
        // long second = DateUtil.getTimespan(orderWork.getCreateTime(), orderDiscount.getCreateTime(), DateUtil.UNIT_SECOND);
        // if (second < 3) {
        //     return GlobalConsts.NO;
        // }
        //
        // // A 通过批次Id查询 是否是外部优惠券
        // boolean thirdCoupon = false;
        // CoupBatchDIO coupBatchDIO = new CoupBatchDIO();
        // coupBatchDIO.setBatchId(orderDiscount.getSourceId());
        // log.debug("#oms#masterworkdetail 获取优惠券批次类型入参:{}", JSON.toJSONString(coupBatchDIO));
        // ResponseDTO<CoupBatchDRO> batchDROResponseDTO = coupRemoteService.getCoupontypeByBatchId(coupBatchDIO);
        // log.debug("#oms#masterworkdetail 获取优惠券批次类型出参:{}", JSON.toJSONString(batchDROResponseDTO));
        // if (batchDROResponseDTO.getStatusBool() && batchDROResponseDTO.getData() != null && Objects.equals(batchDROResponseDTO.getData().getCouponType(), GlobalConsts.YES)) {
        //     thirdCoupon = true;
        // }
        //
        // if (thirdCoupon) {
        //     return GlobalConsts.NO;
        // }
        //
        // return GlobalConsts.YES;
    }

    /**
     * 工单简版详情
     *
     * @param orderId
     * @param workId
     */
    @Override
    public WorkDetailDTO getWorkSimpleDetail(Integer plat, Long orderId, Long workId) throws OmsBaseException {
        WorkDetailDTO workDetailDTO = new WorkDetailDTO();

        /*基本信息*/

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (orderWork == null) {
            throw new OmsBaseException("无效的工单");
        }
//        boolean isCancel = Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DISCARD) ||
//                (Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_FAIL) && Objects.isNull(orderWork.getCompleteTime()));
//        if (isCancel) {
//            throw new OmsBaseException("订单已取消");
//        }

        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderId);

        /////////////////////////////////////////////////////////////////////////////////////////////////

        workDetailDTO.setOrderId(orderId);
        workDetailDTO.setWorkId(workId);
        workDetailDTO.setMasterId(orderWork.getMasterId());
        workDetailDTO.setCompanyId(orderWork.getCompanyId());
        workDetailDTO.setManageCompanyId(orderWork.getManageCompanyId());
        workDetailDTO.setType(orderWork.getType());
        workDetailDTO.setBizType(orderWork.getBizType());
        workDetailDTO.setStatus(orderWork.getStatus());
        workDetailDTO.setResultStatus(orderWork.getResultStatus());
        workDetailDTO.setDutyTime(orderWork.getDutyTime());
        workDetailDTO.setServCategId(orderDetail.getServCategId());
        workDetailDTO.setServCategName(orderDetail.getServCategName());
        workDetailDTO.setProductInfo(orderDetail.getProductInfo());
        workDetailDTO.setFault(orderDetail.getFault());
        workDetailDTO.setRemark(orderDetail.getRemark());
        workDetailDTO.setUserName(orderDetail.getUserName());
        workDetailDTO.setContactName(orderDetail.getContactName());
        workDetailDTO.setProvinceId(orderDetail.getProvinceId());
        workDetailDTO.setProvinceName(orderDetail.getProvinceName());
        workDetailDTO.setCityId(orderWork.getCityId());
        workDetailDTO.setCityName(orderDetail.getCityName());
        workDetailDTO.setCountyId(orderDetail.getCountyId());
        workDetailDTO.setCountyName(orderDetail.getCountyName());
        workDetailDTO.setStreet(orderDetail.getStreet());
        //workDetailDTO.setAddress(orderDetail.getAddress());
        workDetailDTO.setAddress("****");
        workDetailDTO.setFinalPrice(orderWork.getFinalPrice());
        workDetailDTO.setServItemType(orderWork.getServItemType());
        workDetailDTO.setVisitUserId(orderWork.getVisitUserId());
        workDetailDTO.setUserId(orderWork.getUserId());
        workDetailDTO.setContactTime(orderWork.getContactTime());
        workDetailDTO.setRecommenderId(orderWork.getRecommenderId());
        workDetailDTO.setRecommenderType(orderWork.getRecommenderType());

        // 小号1绑定状态判断
        if (this.getXnoBindStatus(orderDetail.getBindTelephone(), orderDetail.getBindStatus())) {
            workDetailDTO.setTelephone(orderDetail.getBindTelephone());
        } else {
            workDetailDTO.setTelephone(orderDetail.getTelephone());
        }
        // 小号2绑定状态判断
        if (this.getXnoBindStatus(orderDetail.getBindTelephone2(), orderDetail.getBindStatus())) {
            workDetailDTO.setTelephone2(orderDetail.getBindTelephone2());
        } else {
            workDetailDTO.setTelephone2(orderDetail.getTelephone2());
        }
        // 小号3绑定状态判断
        if (this.getXnoBindStatus(orderDetail.getBindTelephone3(), orderDetail.getBindStatus())) {
            workDetailDTO.setTelephone3(orderDetail.getBindTelephone3());
        } else {
            workDetailDTO.setTelephone3(orderDetail.getTelephone3());
        }


        /*产品列表*/
        List<OrderProduct> productList = orderProductService.listOrderProductByOrderId(orderId);
        workDetailDTO.setProductList(productList);

        // 渠道名称
        String channelName = StringUtil.isBlank(orderWork.getChannelAnotherName()) ?
                orderWork.getChannelName() :
                orderWork.getChannelAnotherName();
        workDetailDTO.setChannelName(channelName);
        workDetailDTO.setChannelId(orderWork.getChannelId());


        // 订单标签处理
        this.processOrderTag(workDetailDTO);

        return workDetailDTO;
    }

    /**
     * 历史工单详情
     *
     * @param orderId
     * @param workId
     * @param masterId
     */
    @Override
    public WorkDetailDTO getHisWorkDetail(Integer plat, Long orderId, Long workId, Integer masterId, Integer agent)
            throws OmsBaseException {
        WorkDetailDTO workDetailDTO = new WorkDetailDTO();

        /*基本信息*/

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (orderWork == null) {
            throw new OmsBaseException("工单已被处理");
        }

        OrderDetail orderDetail = orderDetailService.findOrderDetailByKey(orderId);
        // 是否啄木鸟自营
        boolean zmnDirectly = Objects.equals(orderWork.getPlatWork(), GlobalConsts.PLAT_MARK_ZMN) && Objects
                .equals(agent, 1);

        /////////////////////////////////////////////////////////////////////////////////////////////////

        workDetailDTO.setOrderId(orderId);
        workDetailDTO.setWorkId(workId);
        workDetailDTO.setMasterId(orderWork.getMasterId());
        workDetailDTO.setCompanyId(orderWork.getCompanyId());
        workDetailDTO.setManageCompanyId(orderWork.getManageCompanyId());
        workDetailDTO.setType(orderWork.getType());
        workDetailDTO.setGrabType(orderWork.getGrabType());
        workDetailDTO.setStatus(orderWork.getStatus());
        workDetailDTO.setResultStatus(orderWork.getResultStatus());
        workDetailDTO.setDutyTime(orderWork.getDutyTime());
        workDetailDTO.setBizType(orderWork.getBizType());
        workDetailDTO.setServCategId(orderDetail.getServCategId());
        workDetailDTO.setServCategName(orderDetail.getServCategName());
        workDetailDTO.setProductId(orderDetail.getProductId());
        workDetailDTO.setProductInfo(orderDetail.getProductInfo());
        workDetailDTO.setFault(orderDetail.getFault());
        workDetailDTO.setRemark(orderDetail.getRemark());
        workDetailDTO.setUserName(orderDetail.getUserName());
        workDetailDTO.setContactName(orderDetail.getContactName());
        workDetailDTO.setTelephone(orderDetail.getTelephone());
        workDetailDTO.setTelephone2(orderDetail.getTelephone2());
        workDetailDTO.setTelephone3(orderDetail.getTelephone3());
        workDetailDTO.setProvinceId(orderDetail.getProvinceId());
        workDetailDTO.setProvinceName(orderDetail.getProvinceName());
        workDetailDTO.setCityId(orderWork.getCityId());
        workDetailDTO.setCityName(orderDetail.getCityName());
        workDetailDTO.setCountyId(orderDetail.getCountyId());
        workDetailDTO.setCountyName(orderDetail.getCountyName());
        workDetailDTO.setStreet(orderDetail.getStreet());
        workDetailDTO.setAddress(orderDetail.getAddress());
        workDetailDTO.setLongitude(orderDetail.getLongitude());
        workDetailDTO.setLatitude(orderDetail.getLatitude());
        workDetailDTO.setManualCode(orderWork.getManualCode());
        workDetailDTO.setSourceType(orderWork.getSourceType());
        workDetailDTO.setMember(orderWork.getMember());
        workDetailDTO.setStandardPrice(orderWork.getStandardPrice());
        workDetailDTO.setDelivery(orderWork.getDelivery());
        workDetailDTO.setWaitPart(orderWork.getWaitPart());
        workDetailDTO.setPartUse(orderWork.getPartUse());
        workDetailDTO.setPartReimburse(orderWork.getPartReimburse());
        workDetailDTO.setPartReimburseAmount(orderWork.getPartReimburseAmount());
        workDetailDTO.setPartReimburseStatus(orderWork.getPartReimburseStatus());
        workDetailDTO.setPartReimburseTime(orderWork.getPartReimburseTime());
        workDetailDTO.setFinalPrice(orderWork.getFinalPrice());
        workDetailDTO.setOuterId(orderWork.getOuterId());
        workDetailDTO.setPartRetain(orderWork.getPartRetain());
        // 时间
        workDetailDTO.setAccountTime(orderWork.getAccountTime());
        workDetailDTO.setServiceCompleteTime(orderWork.getServiceCompleteTime());
        workDetailDTO.setCheckoutTime(orderWork.getCheckoutTime());
        workDetailDTO.setFailTime(orderWork.getResultStatus().equals(OrderStatusConsts.WORK_RESULT_FAIL) ? orderWork.getResultTime() : null);

        // 金额
        workDetailDTO.setOriginalAmount(orderWork.getOriginalAmount());
        workDetailDTO.setTotalAmount(orderWork.getTotalAmount());
        workDetailDTO.setMasterAmount(orderWork.getMasterAmount());
        workDetailDTO.setDiscountAmount(orderWork.getDiscountAmount());

        // 提成金额
        ResponseDTO<Integer> engineerReserveAmount = engineerAccountRemoteService.getEngineerReserveAmount(masterId, orderId);
        if (engineerReserveAmount.isSuccess() && engineerReserveAmount.getData() != null) {
            workDetailDTO.setRewardAmount(engineerReserveAmount.getData());
        }

        // 渠道名称
        String channelName = StringUtil.isBlank(orderWork.getChannelAnotherName()) ?
                orderWork.getChannelName() :
                orderWork.getChannelAnotherName();
        workDetailDTO.setChannelName(channelName);
        workDetailDTO.setChannelId(orderWork.getChannelId());

        OrderExtend orderExtend = orderExtendService.findOrderExtendByOrderId(orderId);

        // 查询标识列表
        queryTips(workDetailDTO, orderWork, orderExtend);

        /*产品列表*/
        List<OrderProduct> productList = orderProductService.listOrderProductByOrderId(orderId);
        workDetailDTO.setProductList(productList);

        /*已选服务项列表*/
        List<OrderServiceItem> orderServiceItemList = orderServiceItemService.listByOrderId(orderId);
        workDetailDTO.setOrderServiceItemList(orderServiceItemList);

        /*不是退款单*/
        if (orderWork.getType() != OrderConsts.ORDER_TYPE_REFUND) {

            workDetailDTO.setSupportSaleMember(GlobalConsts.NO);

            /*已选配件列表*/
            List<OrderPart> orderPartList = orderPartService.listByOrderId(orderId);
            workDetailDTO.setOrderPartList(orderPartList);

            /*操作日志*/
            List<OrderLog> orderLogList = orderLogBService.findOrderLogsByMaster(orderId, (long) masterId);
            workDetailDTO.setOrderLogList(orderLogList);

            if (orderExtend != null) {
                // 查询订单贴花照片列表
                String appliqueSrc = orderExtend.getAppliqueSrc();
                if (StringUtil.isNotBlank(appliqueSrc)) {
                    String[] split = appliqueSrc.split(",");
                    workDetailDTO.setAppliqueSrcList(Lists.newArrayList(split));
                }

                // 订单工程师拍照列表
                String imageSrc = orderExtend.getImageSrc();
                if (StringUtil.isNotBlank(imageSrc)) {
                    String[] split = imageSrc.split(",");
                    workDetailDTO.setImageSrcList(Lists.newArrayList(split));
                }

                // 订单工程师工作照列表
                String masterSrc = orderExtend.getMasterSrc();
                if (StringUtil.isNotBlank(masterSrc)) {
                    String[] split = masterSrc.split(",");
                    workDetailDTO.setMasterSrcList(Lists.newArrayList(split));
                }
            }

            // 贴花照审核信息
            List<OrderAttachment> attachmentList = orderAttachmentService.listAttachmentByOrderId(orderId);
            if (CollectionUtils.isNotEmpty(attachmentList)) {
                OrderAttachment orderAttachment = attachmentList.stream()
                        .filter(attachmentItem -> Objects.equals(attachmentItem.getType(), OrderAttachmentTypeEnum.CONSTS_THZ))
                        .findFirst()
                        .orElse(null);

                if (Objects.nonNull(orderAttachment)) {
                    // 组装贴花照审核信息
                    OrderAttachmentAuditDTO orderAttachmentAuditDTO = BeanMapper.map(orderAttachment, OrderAttachmentAuditDTO.class);
                    orderAttachmentAuditDTO.setPictureName(OrderAttachmentTypeEnum.getName(orderAttachment.getType()));
                    workDetailDTO.setAppliqueAuditInfo(orderAttachmentAuditDTO);
                    log.info("贴花照审核数据：{}", orderAttachmentAuditDTO);
                }
            }

            /*保修卡or收据*/
            OrderWarranty orderWarranty = orderWarrantyService.findByOrderId(orderId);
            if (orderWarranty != null) {
                workDetailDTO.setGrantStatus(NumberUtil.isNullOrZero(orderWarranty.getUserId()) ? GlobalConsts.NO : GlobalConsts.YES);
            }
            workDetailDTO.setOrderWarranty(orderWarranty);

            // 是否需要选择保修卡故障（1：否，2：是）
            boolean needSelectWarrantyFault = PremissUtil.needSelectWarrantyFault(orderDetail.getServCategId());
            workDetailDTO.setNeedSelectWarrantyFault(needSelectWarrantyFault ? GlobalConsts.YES : GlobalConsts.NO);

            //  if (needSelectWarrantyFault) {
            /*已选保修项列表*/
            List<OrderWarrantyProduct> orderWarrantyProductList = orderWarrantyProductService.listByOrderId(orderId);
            workDetailDTO.setOrderWarrantyProductList(orderWarrantyProductList);
            //}

            // 是否支持保修卡质保会员  （家电维修&保修卡&距离完成时间90天内）
            long timespan = DateUtil.getTimespan(orderWork.getCompleteTime(), DateUtil.getNow(), DateUtil.UNIT_DAY);
            if (orderWarranty != null && Objects.equals(orderWarranty.getType(), OrderConsts.ORDER_WARRANTY_TYPE_CARD)
                    && Objects.equals(orderWork.getServCategId(), GlobalConsts.SERV_CATEG_REPAIR) && timespan < 90) {
                workDetailDTO.setWarrantyMember(GlobalConsts.YES);
            }

        } // 不是退款单

        /*返修原单信息*/
        if (orderWork.getType() == OrderConsts.ORDER_TYPE_REWORK && orderWork.getOriginalId() != GlobalConsts.NONE) {
            ReworkDetailDTO reworkDetailDTO = this.getReworkDetail(orderWork.getOriginalId(), orderWork.getOriginalId(), orderWork.getMasterId());
            workDetailDTO.setReworkDetail(reworkDetailDTO);
        }

        // 90天以内订单显示，以完成时间起算 & 是否支持单品会员注册 & 过滤退款单
        workDetailDTO.setSupportSingleMemberRegister(GlobalConsts.NO);
        // 和产品赵伟确认只卖新啄安保会员
        //        if (zmnDirectly) {
        //            ResponseDTO<Boolean> permOfCityDTO = memMemberRemoteService.checkPermOfCity(orderWork.getCityId
        //            ());
        //            boolean supportRegisterA = DateUtil.addDays(orderWork.getCompleteTime(), 90).compareTo(new Date
        //            ()) == 1;
        //            Boolean supportRegisterB = permOfCityDTO.getStatusBool();
        //            boolean supportRegisterC = !Objects.equals(orderWork.getType(), OrderConsts.ORDER_TYPE_REFUND);
        //            if (supportRegisterA && supportRegisterB && supportRegisterC) {
        //                workDetailDTO.setSupportSingleMemberRegister(permOfCityDTO.getData() ? GlobalConsts.YES :
        //                GlobalConsts.NO);
        //            }
        //        }

//        checkDaojia58ExtendInfo(orderWork, workDetailDTO);


        // 分润预估
        SharingEstimateVO sharingEstimate = null;
        try {
            sharingEstimate = orderWorkERPQueryBService.findSharingEstimate(orderId, workId, true, true);
            if (Objects.nonNull(sharingEstimate)) {
                workDetailDTO.setSharingEstimate(BeanMapper.map(sharingEstimate, WorkSharingEstimateDTO.class));
            }
        } catch (OmsBaseException e) {
            log.debug("工单[{}]无法获取分润信息:{}", workId, e.getMessage());
        }
        // 失败原因
        if (Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_FAIL)) {
            if (Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_CHECKOUT)
                    || Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_ACCOUNT)) {
                // 收单导致
                Query query = new Query();
                Criteria criteria = new Criteria();
                criteria.and("orderId").is(orderId);
                criteria.and("type").is(OrderLogConsts.ORDER_LOG_TYPE_CHECKOUT);
                query.addCriteria(criteria);
                query.with(Sort.by(Sort.Order.desc("createTime")));
                List<OrderLog> orderLogs = mongoTemplate.find(query, OrderLog.class);
                if (CollectionUtil.isNotNullOrEmpty(orderLogs)) {
                    String[] split = orderLogs.get(0).getContent().split("备注：");
                    if (split.length > 1) {
                        workDetailDTO.setFailReason(split[1]);
                    }
                }
            } else {
                // 取消导致
                OrderRemarkVO orderRemarkVO = orderRemarkBService.findOrderRemarkVO(orderId, workId, OrderConsts.ORDER_REMARK_TYPE_CANCEL);
                if (Objects.nonNull(orderRemarkVO)) {
                    workDetailDTO.setFailReason(orderRemarkVO.getContent());
                    if (CollectionUtil.isNotNullOrEmpty(orderRemarkVO.getDetailVOList())) {
                        List<String> collect = orderRemarkVO.getDetailVOList().stream().map(OrderRemarkDetailVO::getMapName).collect(Collectors.toList());
                        workDetailDTO.setFailReasonList(collect);
                    }
                }
            }
        }

        // 订单标签处理
        this.processOrderTag(workDetailDTO);

        List<OrderVisit> orderVisitList = orderVisitService.listByOrderIdAndMasterIdSrcMaster(orderWork.getOrderId(), orderWork.getMasterId());
        if (CollectionUtil.isNotNullOrEmpty(orderVisitList)) {
            OrderVisit orderVisit = Streams.findLast(orderVisitList.stream()
                            .filter(item -> !Objects.equals(item.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_CANCEL)))
                    .orElse(null);
            if (Objects.nonNull(orderVisit)) {
                workDetailDTO.setMultipleVisitStatus(orderVisit.getVisitStatus());
            }
            // 处理历史
            AtomicInteger depositAmount = new AtomicInteger();
            AtomicInteger progressAmount = new AtomicInteger();
            orderVisitList.forEach(visit -> {
                if (Objects.equals(visit.getVisitStatus(), OrderVisitStatusConsts.ORDER_VISIT_STATUS_CANCEL)) {
                    return;
                }
                if (NumberUtil.isNullOrZero(visit.getAmount())) {
                    return;
                }
                if (Objects.equals(visit.getAmountType(), OrderPayConsts.ORDER_PAY_DEPOSIT)) {
                    depositAmount.addAndGet(visit.getAmount());
                } else {
                    progressAmount.addAndGet(visit.getAmount());
                }
            });
            workDetailDTO.setDepositAmount(depositAmount.get());
            workDetailDTO.setDepositStatus(NumberUtil.isNullOrZero(workDetailDTO.getDepositAmount()) ? GlobalConsts.NO : GlobalConsts.YES);
            workDetailDTO.setProgressAmount(progressAmount.get());
            workDetailDTO.setProgressStatus(NumberUtil.isNullOrZero(workDetailDTO.getProgressAmount()) ? GlobalConsts.NO : GlobalConsts.YES);
        }

        // 是否发起收款--多次上门
        // 当前上门状态是已上门、工单金额不是0、服务分类是防水补漏和墙面翻新
        workDetailDTO.setMultipleAmount(GlobalConsts.NO);
        workDetailDTO.setDeliveryWaitPart(GlobalConsts.NO);
        if (NumberUtil.isNotNullOrZero(orderWork.getOriginalAmount())) {
            if (Objects.equals(orderWork.getServCategId(), ProductConsts.SERV_CATEG_WATERPROOF)
                    || Objects.equals(orderWork.getServCategId(), ProductConsts.SERV_CATEG_METOPE)
                    || Objects.equals(orderWork.getServCategId(), ProductConsts.SERV_CATEG_KITCHEN_TOILET)) {
                workDetailDTO.setMultipleAmount(GlobalConsts.YES);
            } else {
                workDetailDTO.setDeliveryWaitPart(GlobalConsts.YES);
            }
        }

        return workDetailDTO;
    }

    private ReworkDetailDTO getReworkDetail(Long orderId, Long workId, Integer masterId) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (orderWork == null) {
            return null;
        }

        ReworkDetailDTO reworkDetailDTO = new ReworkDetailDTO();
        reworkDetailDTO.setTotalAmount(orderWork.getTotalAmount());
        // 订单金额
        reworkDetailDTO.setOriginalAmount(orderWork.getOriginalAmount());

        /*已选配件列表*/
        List<OrderPart> orderPartList = orderPartService.listByOrderId(orderId);
        reworkDetailDTO.setOrderPartList(orderPartList);

        /*已选保修列表*/
        List<OrderWarrantyProduct> orderWarrantyProductList = orderWarrantyProductService.listByOrderId(orderId);
        reworkDetailDTO.setOrderWarrantyProductList(orderWarrantyProductList);

        // 原单信息
        reworkDetailDTO.setCompleteTime(orderWork.getCompleteTime());
        reworkDetailDTO.setMasterName(orderWork.getMasterName());

        //原单产品
        List<OrderProduct> orderProductList = orderProductService.listOrderProductByOrderId(orderId);
        if (CollectionUtil.isNotNullOrEmpty(orderProductList)) {
            reworkDetailDTO.setShowProductName(orderProductList.get(0).getShowProductName());
        }

        // 是否本人订单
        if (Objects.equals(masterId, orderWork.getMasterId())) {
            reworkDetailDTO.setOrderSource(GlobalConsts.YES);
        } else {
            reworkDetailDTO.setOrderSource(GlobalConsts.NO);
        }

        return reworkDetailDTO;
    }

    /**
     * 工单完成
     *
     * @param completeDTO
     * @return
     */
    @Override
    public void updateComplete(CompleteDTO completeDTO) {
        OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(completeDTO.getOrderId(), completeDTO.getWorkId());

        Date now = DateUtil.getNow();

        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(completeDTO.getOrderId());
        updateOrderWork.setWorkId(completeDTO.getWorkId());
        updateOrderWork.setStatus(completeDTO.getStatus());
        updateOrderWork.setCompleteOnSite(completeDTO.getCompleteOnSite());
        updateOrderWork.setCompleteTime(now);
        updateOrderWork.setCompleterId(completeDTO.getOperatorId());
        updateOrderWork.setChannelAmount(completeDTO.getChannelAmount());// 渠道费
        updateOrderWork.setDelivery(GlobalConsts.NO);
        updateOrderWork.setWaitPart(GlobalConsts.NO);
        Date time = Optional.ofNullable(orderWork.getDutyTime()).orElse(now);
        // 领单、上门时间处理
        if (Objects.isNull(orderWork.getTakeTime())) {
            updateOrderWork.setTakeTime(time);
        }
        if (Objects.isNull(orderWork.getVisitTime())) {
            updateOrderWork.setVisitTime(time);
        }
        if (Objects.isNull(orderWork.getServiceCompleteTime())) {
            updateOrderWork.setServiceCompleteTime(DateUtil.getNow());
        }

        if (completeDTO.isUpdatePayStatus()) {
            Date date = DateUtil.getNow();
            updateOrderWork.setPayStatus(PayConsts.PAY_STATUS_DONE);
            updateOrderWork.setPayTime(date);
            updateOrderWork.setMasterPayStatus(PayConsts.PAY_STATUS_DONE);
            updateOrderWork.setMasterPayTime(date);
        }

        if (Objects.equals(GlobalConsts.YES, completeDTO.getAutoServiceComplete())) {
            updateOrderWork.setServiceCompleterId(completeDTO.getOperatorId());
            updateOrderWork.setServiceCompleteTime(now);
            updateOrderWork.setServiceCompleteReviewStatus(OrderConsts.REVIEW_STATUS_SUCCESS);
            updateOrderWork.setServiceCompleteReviewerId(completeDTO.getOperatorId());
            updateOrderWork.setServiceCompleteReviewTime(now);
        }

        // 如果未操作过配件默认未使用配件
        if (Objects.equals(orderWork.getPartUse(), GlobalConsts.NONE)) {
            updateOrderWork.setPartUse(GlobalConsts.NO);
        }

        masterWorkService.updateComplete(updateOrderWork);
    }

    /**
     * 记录工程师联系用户
     *
     * @param contactUserDTO
     * @return
     */
    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_CONTACT_USER)
    public void saveContactUser(ContactUserDTO contactUserDTO) {
        // 更新联系时间
        updateContactTime(contactUserDTO);
    }


    @Override
    public void updateContactTime(ContactUserDTO contactUserDTO) {

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(contactUserDTO.getOrderId(), contactUserDTO.getWorkId());
        if (orderWork == null) {
            return;
        }

        // 处理联系时间为空
        Date callTime = Optional.ofNullable(contactUserDTO.getCallTime()).orElse(new Date());

        // 修改进行中工单
        MasterWorking masterWorking = new MasterWorking();
        masterWorking.setWorkId(orderWork.getWorkId());
        masterWorking.setContactTime(callTime);
        masterWorkingService.updateMasterWorking(masterWorking);

        // 已经记录过联系用户时间了，就不再记录了
        if (orderWork.getContactTime() != null) {
            return;
        }
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(contactUserDTO.getOrderId());
        updateOrderWork.setWorkId(contactUserDTO.getWorkId());
        updateOrderWork.setContactTime(callTime);
        masterWorkService.updateContactUser(updateOrderWork);
    }

    // 处理普通通话记录
    @Override
    public CallRecordLogDTO processNormalCallRecord(ContactUserDTO contactUserDTO) {

        OrderDetail orderDetail= orderDetailService.findOrderDetailByKey(contactUserDTO.getOrderId());
        // todo fubiao
        log.info("processNormalCallRecord#getEngineerById 入参 [{}]",contactUserDTO.getMasterId());
        ResponseDTO<ForeignEngineerBasicInfoDRO> engineerByEngineerId = engineerListRemoteService.getEngineerById(contactUserDTO.getMasterId());
        log.info("processNormalCallRecord#getEngineerById 出参 [{}]",JSON.toJSONString(engineerByEngineerId));

        CallRecordLogDTO callRecordLogDTO = new CallRecordLogDTO();
        callRecordLogDTO.setOrderId(contactUserDTO.getOrderId());
        // 2020-07-30 14:05:44,已接通，通话时长1分7秒
        // 2020-07-30 14:22:47,未接通
        String[] split = contactUserDTO.getCallDesc().split(",");
        if (split.length == 2) {
            // 处理中文逗号
            String[] split1 = split[1].split("，");
            if (split1.length == 2) {
                split = new String[]{split[0], split1[0], split1[1]};
            }
        }
        if (split.length == 3) {
            // 代表已接通
            // 格式存储通话时长
            String hour = "00";
            String min = "00";
            String second;
            int minnum = 0;
            int secondnum = 0;
            // 提取字符串的时分秒
            String[] strs = split[2].split("分");

            if (strs.length == 2) {
                minnum = getNum(strs[0]);
                min = minnum / 10 > 0 ? String.valueOf(minnum) : "0" + minnum;
                secondnum = getNum(strs[1]);
            } else {
                secondnum = getNum(split[2]);
            }
            second = secondnum / 10 > 0 ? String.valueOf(secondnum) : "0" + secondnum;
            callRecordLogDTO.setCallDuration(hour + ":" + min + ":" + second);
            callRecordLogDTO.setStartTime(contactUserDTO.getCallTime());
            int sum = minnum == 0 ? secondnum : minnum * 60 + secondnum;
            Date finishTime = DateUtil.addSecond(contactUserDTO.getCallTime(), sum);
            callRecordLogDTO.setFinishTime(finishTime);
            callRecordLogDTO.setStatus(3);
        } else {
            callRecordLogDTO.setStatus(2);
        }
        callRecordLogDTO.setCallerNo(engineerByEngineerId.getData().getMobile());
        callRecordLogDTO.setCalledNo(orderDetail.getTelephone());
        callRecordLogDTO.setCallType(1);
        callRecordLogDTO.setCalledType(2);
        return callRecordLogDTO;
    }

    /**
     * 判断工单是否确认过报价 用户确认过报价（后台报价默认为确认过报价，报价状态不能回滚）
     *
     * @param orderId
     * @return
     */
    @Override
    public boolean haveConfirmQuotation(Long orderId) {
        // 用户确认过报价 或 后台确认过报价，则为已确认过报价
        String confirmRedisKey = String.format(RedisKeyConsts.USER_HAVE_CONFIRM_QUOTATION_KEY, orderId);
        return redisManager.exists(confirmRedisKey);
    }

    /**
     * 工单报价显示相关
     *
     * @param orderWork
     */
    @Override
    public WorkQuotationShowDTO getQuotationShow(OrderWork orderWork) {
        WorkQuotationShowDTO workQuotationShowDTO = new WorkQuotationShowDTO();
        workQuotationShowDTO.setWorkId(orderWork.getWorkId());
        workQuotationShowDTO.setQrCodeUrl(String.format(quotationQrcodeUrl, orderWork.getWorkId()));
        workQuotationShowDTO.setWechatOpenUser(GlobalConsts.NO);
        workQuotationShowDTO.setSendWechatTemplate(GlobalConsts.NO);

        if (!servItemBService.isQuotationNotThreeType(orderWork.getServItemType())) {
            log.error("#oms#getQuotationShow 非计价工单，不发送计价模版消息");
            return workQuotationShowDTO;
        }

        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            log.error("#oms#getQuotationShow 订单已完结");
            return workQuotationShowDTO;
        }
        Long visitUserId = orderWork.getVisitUserId();
        if (NumberUtil.isNullOrZero(visitUserId)) {
            log.error("#oms#getQuotationShow 扫码用户不存在");
            return workQuotationShowDTO;
        }

        String openId = messageGetSendInfoService.getOrderUserRelationOpenId(orderWork.getOrderId(), orderWork.getPlatWork(), visitUserId);
        if (StringUtils.isBlank(openId)) {
            log.error("#oms#getQuotationShow 未找到上门扫码用户的openId");
            return workQuotationShowDTO;
        }

        String redisKey = String.format(RedisKeyConsts.WECHAT_SEND_QUOTATION_TEMPLATE_KEY, String.valueOf(orderWork.getWorkId()), openId);
        String redisValue = redisManager.get(redisKey);
        workQuotationShowDTO.setWechatOpenUser(GlobalConsts.YES);
        workQuotationShowDTO.setSendWechatTemplate(StringUtil.isBlank(redisValue) ? GlobalConsts.NO : GlobalConsts.YES);
        return workQuotationShowDTO;
    }


    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_VISIT_QR)
    public OrderVisitQrCodeVO visitUserQrCode(MasterVisitQrDTO visitQrDTO) {
        // 仅记录日志
        OrderVisitQrCodeVO vo = new OrderVisitQrCodeVO();
        vo.setBind(true);
        vo.setOrderId(0L);
        return vo;
    }

    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_USER_ATTENTION_QR)
    public OrderVisitQrCodeVO userAttentionQrCode(MasterVisitQrDTO visitQrDTO) {
        // 仅记录日志
        OrderVisitQrCodeVO vo = new OrderVisitQrCodeVO();
        vo.setBind(true);
        vo.setOrderId(0L);
        return vo;
    }

    /**
     * 百分比转万分比（元转分）
     *
     * @param percentage
     * @return
     */
    private int getTenThousandRate(BigDecimal percentage) {
        return percentage.movePointRight(2).intValue();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_MASTER_MODIFY_DUTY_TIME)
    public void updateDutyTimeWithNoStock(ModifyDutyTimeDTO modifyDutyTimeDTO) throws OmsBaseException {
        OrderWork orderWork = orderWorkService.findMasterWorkDetail(modifyDutyTimeDTO.getOrderId(), modifyDutyTimeDTO.getWorkId(), modifyDutyTimeDTO.getMasterId());
        if (orderWork == null) {
            throw new OmsBaseException(OrderFailConsts.FAIL_DATA_CHANGE_ORDER_NOMASTER, "无效的工单");
        }

        if (Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_COMPLETE)
                || !Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            throw new OmsBaseException(OrderFailConsts.FAIL_DATA_CHANGE_ORDER_STATUS, "工单不在进行中");
        }

        StockWhiteDTO stockWhiteDTO = StockWhiteDTO.builder()
                .workCityId(orderWork.getCityId())
                .masterId(modifyDutyTimeDTO.getMasterId())
                .build();
        boolean whiteByAllConditions = orderStockBService.isWhiteByAllConditions(stockWhiteDTO);
        if (!whiteByAllConditions) {
            Date dutyDay;
            if (Objects.nonNull(orderWork.getDutyTime())) {
                dutyDay = DateUtil.dateFormatToDate(orderWork.getDutyTime(), DateUtil.FORMAT_DATE);
            } else {
                dutyDay = new Date();
            }

            // 相差天数（含当天）
            Date newDutyDay = DateUtil.dateFormatToDate(modifyDutyTimeDTO.getDutyTime(), DateUtil.FORMAT_DATE);
            Date todayTime = DateUtil.dateFormatToDate(new Date(), DateUtil.FORMAT_DATE);
            long betweenDate = (newDutyDay.getTime() - todayTime.getTime()) / (60 * 60 * 24 * 1000) + 1L;

            if (betweenDate < 0) {
                throw new OmsBaseException("预约时间不能小于当天");
            }

            switch (orderWork.getPlatWork()) {
                case GlobalConsts.PLAT_MARK_ZMN:
                case GlobalConsts.PLAT_MARK_CNHB: {
                    if (orderWork.getDutyTime() == null) {
                        // 无预约时间，允许改为最近7天的范围（含当天）
                        if (betweenDate > 7) {
                            throw new OmsBaseException("只能修改为含今天的7天内");
                        }
                    } else {
                        // 有预约时间，只能修改预约时间次日内时间
                        Date maxDutyDay = DateUtil.addDays(dutyDay, 1);
                        if (maxDutyDay.getTime() < newDutyDay.getTime()) {
                            throw new OmsBaseException("请在当前时间到" + DateUtil.toString(maxDutyDay, "MM月dd日") + "内修改");
                        }

                    }

                    break;
                }
                case GlobalConsts.PLAT_MARK_YEYX: {
                    // 允许改为最近7天的范围（含当天）
                    if (betweenDate > 7) {
                        throw new OmsBaseException("只能修改为含今天的7天内");
                    }
                }
                case GlobalConsts.PLAT_MARK_SAAS: {

                    // 允许改为最近30天的范围（含当天）
                    if (betweenDate > 30) {
                        throw new OmsBaseException("只能修改为含今天的30天内");
                    }

                    break;

                }

                default: {
                    throw new OmsBaseException("未知平台");
                }
            }
        }

        // 保存新的预约时间
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setWorkId(modifyDutyTimeDTO.getWorkId());
        updateOrderWork.setOrderId(modifyDutyTimeDTO.getOrderId());
        updateOrderWork.setDutyTime(modifyDutyTimeDTO.getDutyTime());
        updateOrderWork.setDutyStatus(modifyDutyTimeDTO.getDutyStatus());
        updateOrderWork.setNextContactTime(modifyDutyTimeDTO.getNextContactTime());
        orderWorkService.updateOrderWorkDutyTimeByKey(updateOrderWork);

        // 保存新的预约时间到进行中工单表 & 工程师排班成功
        MasterWorking masterWorking = new MasterWorking();
        masterWorking.setWorkId(modifyDutyTimeDTO.getWorkId());
        masterWorking.setDutyTime(modifyDutyTimeDTO.getDutyTime());
        masterWorking.setWaitScheduling(GlobalConsts.YES);
        masterWorkingService.updateMasterWorking(masterWorking);

    }

    /**
     * 修改预约时间
     *
     * @param modifyDutyTimeDTO
     */
    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_MASTER_MODIFY_DUTY_TIME)
    public void updateDutyTime(ModifyDutyTimeDTO modifyDutyTimeDTO) throws OmsBaseException {
        OrderWork orderWork = orderWorkService.findMasterWorkDetail(modifyDutyTimeDTO.getOrderId(), modifyDutyTimeDTO.getWorkId(), modifyDutyTimeDTO.getMasterId());
        if (orderWork == null) {
            throw new OmsBaseException(OrderFailConsts.FAIL_DATA_CHANGE_ORDER_NOMASTER, "无效的工单");
        }

        if (Objects.equals(orderWork.getStatus(), OrderStatusConsts.WORK_STATUS_COMPLETE)
                || !Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)) {
            throw new OmsBaseException(OrderFailConsts.FAIL_DATA_CHANGE_ORDER_STATUS, "工单不在进行中");
        }

        StockWhiteDTO stockWhiteDTO = StockWhiteDTO.builder()
                .workCityId(orderWork.getCityId())
                .masterId(modifyDutyTimeDTO.getMasterId())
                .build();
        boolean whiteByAllConditions = orderStockBService.isWhiteByAllConditions(stockWhiteDTO);
        if (!whiteByAllConditions) {
            Date dutyDay;
            if (Objects.nonNull(orderWork.getDutyTime())) {
                dutyDay = DateUtil.dateFormatToDate(orderWork.getDutyTime(), DateUtil.FORMAT_DATE);
            } else {
                dutyDay = new Date();
            }

            // 相差天数（含当天）
            Date newDutyDay = DateUtil.dateFormatToDate(modifyDutyTimeDTO.getDutyTime(), DateUtil.FORMAT_DATE);
            Date todayTime = DateUtil.dateFormatToDate(new Date(), DateUtil.FORMAT_DATE);
            long betweenDate = (newDutyDay.getTime() - todayTime.getTime()) / (60 * 60 * 24 * 1000) + 1L;

            if (betweenDate < 0) {
                throw new OmsBaseException("预约时间不能小于当天");
            }

            switch (orderWork.getPlatWork()) {
                case GlobalConsts.PLAT_MARK_ZMN:
                case GlobalConsts.PLAT_MARK_CNHB: {
                    if (orderWork.getDutyTime() == null) {
                        // 无预约时间，允许改为最近7天的范围（含当天）
                        if (betweenDate > 7) {
                            throw new OmsBaseException("只能修改为含今天的7天内");
                        }
                    } else {
                        // 有预约时间，只能修改预约时间次日内时间，并且只能修改两次
                        Date maxDutyDay = DateUtil.addDays(dutyDay, 1);
                        if (maxDutyDay.getTime() < newDutyDay.getTime()) {
                            throw new OmsBaseException("请在当前时间到" + DateUtil.toString(maxDutyDay, "MM月dd日") + "内修改");
                        }

                    /*String key = String.format(RedisKeyConsts.MASTER_MODIFY_DUTY_TIME_COUNT_KEY, modifyDutyTimeDTO.getMasterId(),
                            modifyDutyTimeDTO.getWorkId(), today);
                    String value = redisManager.get(key);
                    int count = 0;

                    if (StringUtil.isNotBlank(value)) {
                        count = Integer.valueOf(value);
                    }

                    if (count >= 2) {
                        throw new OmsBaseException("修改次数已达上限");
                    }

                    // 保存修改计数
                    count++;
                    redisManager.setex(key, count + "", MASTER_MODIFY_DUTY_TIME_COUNT_SECOND);*/
                    }

                    break;
                }
                case GlobalConsts.PLAT_MARK_YEYX: {
                    // 允许改为最近7天的范围（含当天）
                    if (betweenDate > 7) {
                        throw new OmsBaseException("只能修改为含今天的7天内");
                    }
                }
                case GlobalConsts.PLAT_MARK_SAAS: {

                    // 允许改为最近30天的范围（含当天）
                    if (betweenDate > 30) {
                        throw new OmsBaseException("只能修改为含今天的30天内");
                    }

                    break;

                }

                default: {
                    throw new OmsBaseException("未知平台");
                }
            }
        }

        // 保存新的预约时间
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setWorkId(modifyDutyTimeDTO.getWorkId());
        updateOrderWork.setOrderId(modifyDutyTimeDTO.getOrderId());
        updateOrderWork.setDutyTime(modifyDutyTimeDTO.getDutyTime());
        updateOrderWork.setDutyStatus(modifyDutyTimeDTO.getDutyStatus());
        updateOrderWork.setNextContactTime(modifyDutyTimeDTO.getNextContactTime());
        orderWorkService.updateOrderWorkDutyTimeByKey(updateOrderWork);

        // 保存新的预约时间到进行中工单表 & 工程师排班成功
        MasterWorking masterWorking = new MasterWorking();
        masterWorking.setWorkId(modifyDutyTimeDTO.getWorkId());
        masterWorking.setDutyTime(modifyDutyTimeDTO.getDutyTime());
        masterWorking.setWaitScheduling(GlobalConsts.YES);
        masterWorkingService.updateMasterWorking(masterWorking);

        // 占用库存
        LockStockDTO lockStockDTO = LockStockDTO.builder()
                .orderId(updateOrderWork.getOrderId())
                .workId(updateOrderWork.getWorkId())
                .isExcludeThisOrder(true)
                .isMobileLockStock(true)
                .build();
        orderStockBService.takeUpStock(lockStockDTO);
    }

    /**
     * 配件保留申请
     *
     * @param masterPartRetainDTO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_PART_RETAIN, beforeProceed = false)
    public void updatePartRetain(MasterPartRetainDTO masterPartRetainDTO) {
        OrderWork updateOrderWork = new OrderWork();
        updateOrderWork.setOrderId(masterPartRetainDTO.getOrderId());
        updateOrderWork.setWorkId(masterPartRetainDTO.getWorkId());
        updateOrderWork.setPartRetain(masterPartRetainDTO.getRetainPart());
        updateOrderWork.setPartUse(masterPartRetainDTO.getPartUse());
        orderWorkService.updatePartRetainByKey(updateOrderWork);
    }


//    /**
//     * 检查到家58额外信息
//     * 1.资料是否需要完善
//     * 2.是否需要展示提示信息
//     * @param orderWork
//     * @param workDetailDTO
//     */
//    private void checkDaojia58ExtendInfo(OrderWork orderWork, WorkDetailDTO workDetailDTO) {
//        if (OrderConsts.CHANNEL_ID_DJ58_DAG != orderWork.getChannelId()) {
//            workDetailDTO.setReplenishMemberInfo(GlobalConsts.NO);
//            workDetailDTO.setShowTips(GlobalConsts.NO);
//            return;
//        }
//        // 校验是否需要完善资料
//        ResponseDTO<Long> dataComplete = vasOrderListRemoteService.isDataComplete(orderWork.getWorkId());
//        if (dataComplete.isSuccess()) {
//            workDetailDTO.setReplenishMemberInfo(GlobalConsts.YES);
//            workDetailDTO.setReplenishOrderId(String.valueOf(dataComplete.getData()));
//        } else {
//            workDetailDTO.setReplenishMemberInfo(GlobalConsts.NO);
//        }
//
//        boolean isShwoTips =
//                (!dataComplete.isSuccess()) && OrderConsts.CHANNEL_ID_DJ58_DAG == orderWork.getChannelId()
//                        && SERV_CATEGE_APPLIANCE_REPAIR == orderWork.getServCategId() && DAOJIA58_SHOWTPIS_CITY_LIST
//                        .contains(orderWork.getCityId()) && DAOJIA58_SHOWCATEGID_LIST
//                        .contains(orderWork.getShowCategId());
//
//        //        workDetailDTO.setShowTips(isShwoTips ? GlobalConsts.YES : GlobalConsts.NO);
//        workDetailDTO.setShowTips(GlobalConsts.NO);
//    }

    /**
     * 发送用户支付消息
     *
     * @param orderId
     * @param workId
     * @param payMsgType
     */
    @Override
    public boolean sendWaitPayNotice(Long orderId, Long workId, Integer payMsgType) throws OmsBaseException {

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (Objects.isNull(orderWork) || NumberUtil.isNullOrZero(orderWork.getVisitUserId())) {
            OrderExtend orderExtend = orderExtendService.findOrderExtendByOrderId(orderId);
            if (Objects.isNull(orderExtend) || NumberUtil.isNullOrZero(orderExtend.getWeChatScanUserId())) {
                log.info("sendWaitPayNotice 发送失败--上门用户不存在");
                throw new OmsBaseException(OmsErrorCodeConsts.ERROR_WECHAT_NO_ATTENTION_CODE,"上门用户不存在");
            }
            orderWork.setVisitUserId(orderExtend.getWeChatScanUserId());
        }
        // 检验用户是否关注
        checkAttentionWeChat(orderWork);
        // 发送待支付消息
        return messageWeChatTemplateService.sendDesignatedUserWeChatTemplate(orderId, MessageRuleIdConsts.ZMN_MSG_RULEID_ORDER_PAY, orderWork.getVisitUserId());
    }

    /**
     * 发送用户支付消息
     *
     * @param orderId
     * @param workId
     */
    @Override
    public boolean sendWaitPayNotice(Long orderId, Long workId, Long visitUserId, Long orderPayId) {

        // 发送待支付消息
        return messageWeChatTemplateService.sendDesignatedOpenIdWeChatTemplate(orderId, MessageRuleIdConsts.ZMN_MSG_RULEID_ORDER_PAY, visitUserId, null, orderPayId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void completeCleanService(ModifyOrderWorkAttachmentDIO modifyOrderWorkAttachmentDIO) throws OmsBaseException {
        Long workId = modifyOrderWorkAttachmentDIO.getWorkId();
        Long orderId = modifyOrderWorkAttachmentDIO.getOrderId();
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        OrderAttachmentQuery query = OrderAttachmentQuery.builder()
                .bizType(orderWork.getBizType())
                // 写死查询清洁服务后照片
                .categIds(Arrays.asList(171))
                .channelId(orderWork.getChannelId())
                .orderId(orderId)
                .servCategId(orderWork.getServCategId())
                .workId(workId)
                .build();
        WorkAttachmentDRO workAttachmentDRO = attachmentBService.getOrderAttachmentAndConfigByQuery(query);
        log.info("查询清洁完成照片，入参：{}，出参：{}",query, JSON.toJSONString(workAttachmentDRO));
        if (Objects.nonNull(workAttachmentDRO) && CollectionUtil.isNotNullOrEmpty(workAttachmentDRO.getPictureList())){
            Integer requiredFlag = workAttachmentDRO.getPictureList().get(0).getRequiredFlag();
            if (Objects.equals(requiredFlag,GlobalConsts.TWO)){
                String src = modifyOrderWorkAttachmentDIO.getSrc();
                if (StringUtils.isBlank(src)){
                    throw new OmsBaseException("请先完成照片拍摄");
                }
            }
        }

        // 完成清洁服务
        MasterWorking masterWorking = new MasterWorking();
        masterWorking.setWorkId(workId);
        masterWorking.setCompleteCleanService(true);
        int updateMasterWorking = masterWorkingService.updateMasterWorking(masterWorking);
        if (updateMasterWorking == 0){
            log.error("完成清洁服务异常:{}",masterWorking);
            throw new OmsBaseException("完成清洁服务异常");
        }

        if (StringUtils.isNotBlank(modifyOrderWorkAttachmentDIO.getSrc())){
            // 更新照片
            ModifyOrderAttachmentDTO modifyOrderAttachmentDTO = BeanMapper.map(modifyOrderWorkAttachmentDIO, ModifyOrderAttachmentDTO.class);
            modifyOrderAttachmentDTO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_MASTER);
            modifyOrderAttachmentDTO.setOperatorId((long)modifyOrderWorkAttachmentDIO.getMasterId());
            orderAttachmentBService.modifyOrderWorkAttachment(modifyOrderAttachmentDTO);
        }

    }

    // 查询订单标签
    private void queryTips(WorkDetailDTO workDetailDTO, OrderWork orderWork, OrderExtend orderExtend) throws OmsBaseException {

        // 标识列表
        workDetailDTO.setVipChannel(this.getVipChannelFlag(orderWork.getChannelId()));
        workDetailDTO.setServItemType(orderWork.getServItemType());
        if (Objects.nonNull(orderExtend)) {
            workDetailDTO.setAllowRefund(orderExtend.getAllowRefund());
        }
        workDetailDTO.setFinalPrice(orderWork.getFinalPrice());
        workDetailDTO.setDelivery(orderWork.getDelivery());
        workDetailDTO.setWaitPart(orderWork.getWaitPart());
        // 厂商单相关，如邮寄旧件标识，厂商审核标识
        if (Objects.equals(orderWork.getSourceType(), OrderConsts.ORDER_SOURCE_TYPE_FACTORY)
                && Objects.equals(orderWork.getBizType(), com.zmn.consts.GlobalConsts.BIZ_TYPE_F)) {
            boolean waitFactoryReview = false;
            boolean waitPartPost = false;
            FcOrderPartCheckDTO fcPartCheck = orderFactoryPartService.doFactoryPartCheck(orderWork.getOrderId());
            if (fcPartCheck.isContainsFcPart()) {
                waitFactoryReview = fcPartCheck.isContainsWaiting4FcReview();
                waitPartPost = (fcPartCheck.isNeedReturnFcPart() || fcPartCheck.isContainsReturnFcPartWaiting4Post());
            }
            workDetailDTO.setWaitFactoryReview(waitFactoryReview ? GlobalConsts.YES : GlobalConsts.NO);
            workDetailDTO.setWaitPartsPost(waitPartPost ? GlobalConsts.YES : GlobalConsts.NO);
        }
        workDetailDTO.setServiceCompleteReviewStatus(orderWork.getServiceCompleteReviewStatus());
        // 详情增加待取消标识
        MasterWorking masterWorkingByWorkId = masterWorkingService.findMasterWorkingByWorkId(workDetailDTO.getWorkId());
        if (Objects.nonNull(masterWorkingByWorkId)) {
            workDetailDTO.setWaitCancel(masterWorkingByWorkId.getWaitCancel());
        }
        workDetailDTO.setMember(orderWork.getMember());
        workDetailDTO.setDiscountActivityId(orderWork.getDiscountActivityId());
    }

    // 查询渠道vip标识
    private Integer getVipChannelFlag(Integer channelId) {
        ResponseDTO<ChannelDRO> channelRespDTO = channelListRemoteService.getByChannelId(channelId);
        if (channelRespDTO.isSuccess() && channelRespDTO.getData() != null) {
            return Optional.ofNullable(channelRespDTO.getData().getLevel()).orElse(0) == ChannelLevelEnum.VIP.getCode() ? GlobalConsts.YES : GlobalConsts.NO;
        } else {
            return GlobalConsts.NONE;
        }
    }


    // 截取字符串中数字
    private int getNum(String s) {
        // \D 为正则表达式表示非数字
        String[] num_string = s.split("\\D");
        StringBuilder a = new StringBuilder();

        for (String m : num_string) {
            a.append(m);
        }
        //将分离出的重新保存在新数组num中不要直接用num_string，  因为在正则表达式对字符串进行选择时若前面的几个字符不符合要求但num_string数组中仍会存有其位置 是空格
        String[] num = a.toString().split("");
        int[] intArr = new int[num.length];

        for (int i = 0; i < num.length; i++) {
            //将该数组中的数字存入int数组
            intArr[i] = Integer.parseInt(num[i]);
        }
        int result;
        if (intArr.length == 2) {
            result = intArr[0] * 10 + intArr[1];
        } else {
            result = intArr[0];
        }

        return result;
    }

    /**
     * 优质订单
     * @param orderId
     * @return
     */
    private boolean isHighQualityOrder(Long orderId) {

        if (NumberUtil.isNullOrZero(orderId)) {
            return false;
        }

        Integer count = orderTagService.countOrderTagByOrderIdAndTagId(orderId, OrderTagConsts.TAG_ID_HIGH_QUALITY);

        return count > 0 ? true : false;
    }

    /**
     * 高等级工程师
     * @param masterId
     * @param productGroupIds
     * @param cityId
     * @return
     */
    /*  去掉高等级工程师的设置，谢文兵 2022.09.27
    private List<EngineerProductGroupCompositeScoreForDispatchOrderDRO> getHighLevelEngineer(Integer masterId, List<Integer> productGroupIds, Integer cityId) {

        log.debug("getHighLevelEngineer [{}][{}][{}]", masterId, cityId, JSON.toJSONString(productGroupIds));
        // 参数判断
        if (NumberUtil.isNullOrZero(masterId) || CollectionUtil.isNullOrEmpty(productGroupIds)) {
            return null;
        }

        try {
            EngineerProductGroupCompositeScoreForDispatchOrderDIO scoreForDispatchOrderDIO = new EngineerProductGroupCompositeScoreForDispatchOrderDIO();
            List<Integer> engineerIds = new ArrayList<>(1);
            engineerIds.add(masterId);

            scoreForDispatchOrderDIO.setCityId(cityId);
            scoreForDispatchOrderDIO.setProductGroupIds(productGroupIds);
            scoreForDispatchOrderDIO.setEngineerIds(engineerIds);

            ResponseDTO<List<EngineerProductGroupCompositeScoreForDispatchOrderDRO>> responseScoreDTO =
                    compositeServeScoreForOmsListRemoteService.getEngineerCompositeScore(scoreForDispatchOrderDIO);
            log.debug("#CompositeServeScoreForOmsListRemoteService#getEngineerCompositeScore 入参:[{}], 出参：[{}]", JSON.toJSONString(scoreForDispatchOrderDIO),JSON.toJSONString(responseScoreDTO));

            if (!responseScoreDTO.isSuccess()) {
                return null;
            }

            return responseScoreDTO.getData();
        } catch (Exception e) {

            log.info("#getHighLevelEngineer#[{}]判断高等级工程师异常，[{}]", masterId, e.getMessage());
            return null;
        }
    }
    */


    private Map<Long, List<OrderCancelApplyDRO>> getWorkCancelApplyMap(List<MasterWorking> orderWorkList) {
        if (CollectionUtil.isNullOrEmpty(orderWorkList)) {
            return Maps.newHashMap();
        }

        List<Long> orderIds = orderWorkList.stream()
                .filter(e -> Objects.equals(e.getWaitCancel(), GlobalConsts.YES))
                .map(MasterWorking::getWorkId)
                .collect(Collectors.toList());
        if (CollectionUtil.isNullOrEmpty(orderIds)) {
            return Maps.newHashMap();
        }
        OrderCancelApplyQuery orderCancelApplyQuery = new OrderCancelApplyQuery();
        orderCancelApplyQuery.setOrderIdList(orderIds);
        orderCancelApplyQuery.setReviewStatusList(Lists.newArrayList(CancelApplyConsts.ORDER_REVIEW_STATUS_CHECK, CancelApplyConsts.ORDER_REVIEW_STATUS_CHECK_PROCESSING));
        orderCancelApplyQuery.setSearchReason(GlobalConsts.YES);
        log.info("orderCancelApplyListRemoteService.listCancelApplyByQuery query={}", orderCancelApplyQuery);
        ResponseDTO<List<OrderCancelApplyDRO>> dto = orderCancelApplyListRemoteService.listCancelApplyByQuery(orderCancelApplyQuery);
        log.info("orderCancelApplyListRemoteService.listCancelApplyByQuery dto={}", dto);

        if (CollectionUtil.isNullOrEmpty(dto.getData())) {
            return Maps.newHashMap();
        }

        return dto.getData().stream()
                .collect(Collectors.groupingBy(OrderCancelApplyDRO::getWorkId));
    }

    private String getCancelApplyDate(Long workId, Map<Long, List<OrderCancelApplyDRO>> cancelApplyMap) {
        List<OrderCancelApplyDRO> orderCancelApplyDROS = cancelApplyMap.get(workId);
        if (CollectionUtil.isNullOrEmpty(orderCancelApplyDROS)) {
            return null;
        }
        return DateUtil.toString(orderCancelApplyDROS.get(0).getCreateTime());
    }

    private String getCancelApplyReason(Long workId, Map<Long, List<OrderCancelApplyDRO>> cancelApplyMap) {
        List<OrderCancelApplyDRO> orderCancelApplyDROS = cancelApplyMap.get(workId);
        if (CollectionUtil.isNullOrEmpty(orderCancelApplyDROS)) {
            return null;
        }
        List<OrderCancelReasonDRO> cancelReasonList = orderCancelApplyDROS.get(0).getCancelReasonList();
        return cancelReasonList.stream()
                .filter(e -> Objects.equals(e.getReasonSource(), CancelApplyConsts.CANCEL_APPLY_REASON_SOURCE_APPLY))
                .map(OrderCancelReasonDRO::getMapName)
                .findAny()
                .orElse(null);
    }

    /**
     * 检验用户是否关注
     * @param orderWork 工单信息
     */
    private void checkAttentionWeChat(OrderWork orderWork) throws OmsBaseException{
        OrderThirdAppBind orderThirdAppBind = messageGetSendInfoService.getOrderWeChatBindInfoForOrderBy(orderWork.getOrderId(), orderWork.getPlatWork());
        if (Objects.isNull(orderThirdAppBind) || StringUtils.isBlank(orderThirdAppBind.getThirdAppId())) {
            log.info("订单号{}，未找到绑定公众号信息", orderWork.getWorkId());
            throw new OmsBaseException(OmsErrorCodeConsts.ERROR_WECHAT_NO_ATTENTION_CODE, "未找到绑定公众号信息");
        }

        ResponseDTO<Boolean> isAttentionWechat = userThirdListRemoteService.getThirdSubscribeByUserIdAndAppId(orderWork.getVisitUserId(), orderThirdAppBind.getThirdAppId());
        log.info("订单号{},查询用户是否关注公众号,userId:{},appId:{},出参:{}",orderWork.getOrderId(),orderWork.getVisitUserId(),orderThirdAppBind.getThirdAppId(),isAttentionWechat);
        if (isAttentionWechat.isSuccess() && Objects.nonNull(isAttentionWechat.getData())){
            if (!isAttentionWechat.getData()){
                throw new OmsBaseException(OmsErrorCodeConsts.ERROR_WECHAT_NO_ATTENTION_CODE, "发送失败，用户未关注公众号");
            }
        }else {
            log.error("调用getThirdSubscribeByUserIdAndAppId查看用户是否关注公众号接口错误");
            throw new OmsBaseException(OmsErrorCodeConsts.ERROR_WECHAT_NO_ATTENTION_CODE, "查看用户是否关注公众号接口错误");
        }
    }
}
